| 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 "content/browser/presentation/presentation_service_impl.h" | 5 #include "content/browser/presentation/presentation_service_impl.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <iterator> | 10 #include <iterator> |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <utility> | 13 #include <utility> |
| 14 #include <vector> | 14 #include <vector> |
| 15 | 15 |
| 16 #include "base/location.h" | |
| 17 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
| 18 #include "base/single_thread_task_runner.h" | 17 #include "base/test/mock_callback.h" |
| 19 #include "base/test/test_timeouts.h" | |
| 20 #include "base/threading/thread_task_runner_handle.h" | |
| 21 #include "content/public/browser/navigation_handle.h" | 18 #include "content/public/browser/navigation_handle.h" |
| 22 #include "content/public/browser/presentation_service_delegate.h" | 19 #include "content/public/browser/presentation_service_delegate.h" |
| 23 #include "content/public/common/presentation_connection_message.h" | 20 #include "content/public/common/presentation_connection_message.h" |
| 24 #include "content/public/common/presentation_info.h" | 21 #include "content/public/common/presentation_info.h" |
| 25 #include "content/test/test_render_frame_host.h" | 22 #include "content/test/test_render_frame_host.h" |
| 26 #include "content/test/test_render_view_host.h" | 23 #include "content/test/test_render_view_host.h" |
| 27 #include "content/test/test_web_contents.h" | 24 #include "content/test/test_web_contents.h" |
| 28 #include "mojo/public/cpp/bindings/interface_ptr.h" | 25 #include "mojo/public/cpp/bindings/interface_ptr.h" |
| 29 #include "testing/gmock/include/gmock/gmock.h" | 26 #include "testing/gmock/include/gmock/gmock.h" |
| 30 | 27 |
| 31 using ::testing::_; | 28 using ::testing::_; |
| 32 using ::testing::ByRef; | |
| 33 using ::testing::Eq; | 29 using ::testing::Eq; |
| 34 using ::testing::Invoke; | |
| 35 using ::testing::InvokeWithoutArgs; | |
| 36 using ::testing::Mock; | 30 using ::testing::Mock; |
| 37 using ::testing::Return; | 31 using ::testing::Return; |
| 38 using ::testing::SaveArg; | 32 using ::testing::SaveArg; |
| 39 using ::testing::WithArgs; | 33 using NewPresentationCallback = |
| 34 content::PresentationServiceImpl::NewPresentationCallback; |
| 40 | 35 |
| 41 namespace content { | 36 namespace content { |
| 42 | 37 |
| 43 namespace { | 38 namespace { |
| 44 | 39 |
| 40 MATCHER(OptionalIsNotNull, "") { |
| 41 return !!arg; |
| 42 } |
| 43 |
| 44 MATCHER(OptionalIsNull, "") { |
| 45 return !arg; |
| 46 } |
| 47 |
| 45 // Matches content::PresentationInfo. | 48 // Matches content::PresentationInfo. |
| 46 MATCHER_P(InfoEquals, expected, "") { | 49 MATCHER_P(InfoEquals, expected, "") { |
| 47 return expected.presentation_url == arg.presentation_url && | 50 return expected.presentation_url == arg.presentation_url && |
| 48 expected.presentation_id == arg.presentation_id; | 51 expected.presentation_id == arg.presentation_id; |
| 49 } | 52 } |
| 50 | 53 |
| 51 const char kPresentationId[] = "presentationId"; | 54 const char kPresentationId[] = "presentationId"; |
| 52 const char kPresentationUrl1[] = "http://foo.com/index.html"; | 55 const char kPresentationUrl1[] = "http://foo.com/index.html"; |
| 53 const char kPresentationUrl2[] = "http://example.com/index.html"; | 56 const char kPresentationUrl2[] = "http://example.com/index.html"; |
| 54 const char kPresentationUrl3[] = "http://example.net/index.html"; | 57 const char kPresentationUrl3[] = "http://example.net/index.html"; |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 : presentation_url1_(GURL(kPresentationUrl1)), | 243 : presentation_url1_(GURL(kPresentationUrl1)), |
| 241 presentation_url2_(GURL(kPresentationUrl2)), | 244 presentation_url2_(GURL(kPresentationUrl2)), |
| 242 presentation_url3_(GURL(kPresentationUrl3)) {} | 245 presentation_url3_(GURL(kPresentationUrl3)) {} |
| 243 | 246 |
| 244 void SetUp() override { | 247 void SetUp() override { |
| 245 RenderViewHostImplTestHarness::SetUp(); | 248 RenderViewHostImplTestHarness::SetUp(); |
| 246 // This needed to keep the WebContentsObserverSanityChecker checks happy for | 249 // This needed to keep the WebContentsObserverSanityChecker checks happy for |
| 247 // when AppendChild is called. | 250 // when AppendChild is called. |
| 248 NavigateAndCommit(GURL("about:blank")); | 251 NavigateAndCommit(GURL("about:blank")); |
| 249 | 252 |
| 250 auto request = mojo::MakeRequest(&service_ptr_); | |
| 251 EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1); | 253 EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1); |
| 252 TestRenderFrameHost* render_frame_host = contents()->GetMainFrame(); | 254 TestRenderFrameHost* render_frame_host = contents()->GetMainFrame(); |
| 253 render_frame_host->InitializeRenderFrameIfNeeded(); | 255 render_frame_host->InitializeRenderFrameIfNeeded(); |
| 254 service_impl_.reset(new PresentationServiceImpl( | 256 service_impl_.reset(new PresentationServiceImpl( |
| 255 render_frame_host, contents(), &mock_delegate_, nullptr)); | 257 render_frame_host, contents(), &mock_delegate_, nullptr)); |
| 256 service_impl_->Bind(std::move(request)); | |
| 257 | 258 |
| 258 blink::mojom::PresentationServiceClientPtr client_ptr; | 259 blink::mojom::PresentationServiceClientPtr client_ptr; |
| 259 client_binding_.reset( | 260 client_binding_.reset( |
| 260 new mojo::Binding<blink::mojom::PresentationServiceClient>( | 261 new mojo::Binding<blink::mojom::PresentationServiceClient>( |
| 261 &mock_client_, mojo::MakeRequest(&client_ptr))); | 262 &mock_client_, mojo::MakeRequest(&client_ptr))); |
| 262 service_impl_->SetClient(std::move(client_ptr)); | 263 service_impl_->SetClient(std::move(client_ptr)); |
| 263 | 264 |
| 264 presentation_urls_.push_back(presentation_url1_); | 265 presentation_urls_.push_back(presentation_url1_); |
| 265 presentation_urls_.push_back(presentation_url2_); | 266 presentation_urls_.push_back(presentation_url2_); |
| 266 } | 267 } |
| 267 | 268 |
| 268 void TearDown() override { | 269 void TearDown() override { |
| 269 service_ptr_.reset(); | |
| 270 if (service_impl_.get()) { | 270 if (service_impl_.get()) { |
| 271 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1); | 271 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1); |
| 272 service_impl_.reset(); | 272 service_impl_.reset(); |
| 273 } | 273 } |
| 274 RenderViewHostImplTestHarness::TearDown(); | 274 RenderViewHostImplTestHarness::TearDown(); |
| 275 } | 275 } |
| 276 | 276 |
| 277 void Navigate(bool main_frame) { | 277 void Navigate(bool main_frame) { |
| 278 RenderFrameHost* rfh = main_rfh(); | 278 RenderFrameHost* rfh = main_rfh(); |
| 279 RenderFrameHostTester* rfh_tester = RenderFrameHostTester::For(rfh); | 279 RenderFrameHostTester* rfh_tester = RenderFrameHostTester::For(rfh); |
| 280 if (!main_frame) | 280 if (!main_frame) |
| 281 rfh = rfh_tester->AppendChild("subframe"); | 281 rfh = rfh_tester->AppendChild("subframe"); |
| 282 std::unique_ptr<NavigationHandle> navigation_handle = | 282 std::unique_ptr<NavigationHandle> navigation_handle = |
| 283 NavigationHandle::CreateNavigationHandleForTesting( | 283 NavigationHandle::CreateNavigationHandleForTesting( |
| 284 GURL(), rfh, true); | 284 GURL(), rfh, true); |
| 285 // Destructor calls DidFinishNavigation. | 285 // Destructor calls DidFinishNavigation. |
| 286 } | 286 } |
| 287 | 287 |
| 288 void ListenForScreenAvailabilityAndWait(const GURL& url, | 288 void ListenForScreenAvailabilityAndWait(const GURL& url, |
| 289 bool delegate_success) { | 289 bool delegate_success) { |
| 290 base::RunLoop run_loop; | |
| 291 // This will call to |service_impl_| via mojo. Process the message | |
| 292 // using RunLoop. | |
| 293 // The callback shouldn't be invoked since there is no availability | |
| 294 // result yet. | |
| 295 EXPECT_CALL(mock_delegate_, AddScreenAvailabilityListener()) | 290 EXPECT_CALL(mock_delegate_, AddScreenAvailabilityListener()) |
| 296 .WillOnce(DoAll( | 291 .WillOnce(Return(delegate_success)); |
| 297 InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit), | 292 service_impl_->ListenForScreenAvailability(url); |
| 298 Return(delegate_success))); | |
| 299 service_ptr_->ListenForScreenAvailability(url); | |
| 300 run_loop.Run(); | |
| 301 | 293 |
| 302 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_)); | 294 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_)); |
| 303 } | 295 } |
| 304 | 296 |
| 305 void RunLoopFor(base::TimeDelta duration) { | |
| 306 base::RunLoop run_loop; | |
| 307 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 308 FROM_HERE, run_loop.QuitClosure(), duration); | |
| 309 run_loop.Run(); | |
| 310 } | |
| 311 | |
| 312 void SaveQuitClosureAndRunLoop() { | |
| 313 base::RunLoop run_loop; | |
| 314 run_loop_quit_closure_ = run_loop.QuitClosure(); | |
| 315 run_loop.Run(); | |
| 316 run_loop_quit_closure_.Reset(); | |
| 317 } | |
| 318 | |
| 319 void SimulateScreenAvailabilityChangeAndWait(const GURL& url, | 297 void SimulateScreenAvailabilityChangeAndWait(const GURL& url, |
| 320 bool available) { | 298 bool available) { |
| 321 auto listener_it = service_impl_->screen_availability_listeners_.find(url); | 299 auto listener_it = service_impl_->screen_availability_listeners_.find(url); |
| 322 ASSERT_TRUE(listener_it->second); | 300 ASSERT_TRUE(listener_it->second); |
| 323 | 301 |
| 324 base::RunLoop run_loop; | |
| 325 blink::mojom::ScreenAvailability expected_availability = | 302 blink::mojom::ScreenAvailability expected_availability = |
| 326 available ? blink::mojom::ScreenAvailability::AVAILABLE | 303 available ? blink::mojom::ScreenAvailability::AVAILABLE |
| 327 : blink::mojom::ScreenAvailability::UNAVAILABLE; | 304 : blink::mojom::ScreenAvailability::UNAVAILABLE; |
| 328 EXPECT_CALL(mock_client_, | 305 EXPECT_CALL(mock_client_, |
| 329 OnScreenAvailabilityUpdated(url, expected_availability)) | 306 OnScreenAvailabilityUpdated(url, expected_availability)); |
| 330 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | |
| 331 listener_it->second->OnScreenAvailabilityChanged(available); | 307 listener_it->second->OnScreenAvailabilityChanged(available); |
| 332 run_loop.Run(); | 308 base::RunLoop().RunUntilIdle(); |
| 333 } | 309 } |
| 334 | 310 |
| 335 void ExpectReset() { | 311 void ExpectReset() { |
| 336 EXPECT_CALL(mock_delegate_, Reset(_, _)).Times(1); | 312 EXPECT_CALL(mock_delegate_, Reset(_, _)).Times(1); |
| 337 } | 313 } |
| 338 | 314 |
| 339 void ExpectCleanState() { | 315 void ExpectCleanState() { |
| 340 EXPECT_TRUE(service_impl_->default_presentation_urls_.empty()); | 316 EXPECT_TRUE(service_impl_->default_presentation_urls_.empty()); |
| 341 EXPECT_EQ( | 317 EXPECT_EQ( |
| 342 service_impl_->screen_availability_listeners_.find(presentation_url1_), | 318 service_impl_->screen_availability_listeners_.find(presentation_url1_), |
| 343 service_impl_->screen_availability_listeners_.end()); | 319 service_impl_->screen_availability_listeners_.end()); |
| 344 } | 320 } |
| 345 | 321 |
| 346 void ExpectNewPresentationCallbackSuccess( | |
| 347 const base::Optional<PresentationInfo>& info, | |
| 348 const base::Optional<PresentationError>& error) { | |
| 349 EXPECT_TRUE(info); | |
| 350 EXPECT_FALSE(error); | |
| 351 if (!run_loop_quit_closure_.is_null()) | |
| 352 run_loop_quit_closure_.Run(); | |
| 353 } | |
| 354 | |
| 355 void ExpectNewPresentationCallbackError( | |
| 356 const base::Optional<PresentationInfo>& info, | |
| 357 const base::Optional<PresentationError>& error) { | |
| 358 EXPECT_FALSE(info); | |
| 359 EXPECT_TRUE(error); | |
| 360 if (!run_loop_quit_closure_.is_null()) | |
| 361 run_loop_quit_closure_.Run(); | |
| 362 } | |
| 363 | |
| 364 void ExpectConnectionMessages( | |
| 365 const std::vector<PresentationConnectionMessage>& expected_msgs, | |
| 366 const std::vector<PresentationConnectionMessage>& actual_msgs) { | |
| 367 EXPECT_EQ(expected_msgs.size(), actual_msgs.size()); | |
| 368 for (size_t i = 0; i < actual_msgs.size(); ++i) | |
| 369 EXPECT_EQ(expected_msgs[i], actual_msgs[i]); | |
| 370 } | |
| 371 | |
| 372 MockPresentationServiceDelegate mock_delegate_; | 322 MockPresentationServiceDelegate mock_delegate_; |
| 373 MockReceiverPresentationServiceDelegate mock_receiver_delegate_; | 323 MockReceiverPresentationServiceDelegate mock_receiver_delegate_; |
| 374 | 324 |
| 375 std::unique_ptr<PresentationServiceImpl> service_impl_; | 325 std::unique_ptr<PresentationServiceImpl> service_impl_; |
| 376 mojo::InterfacePtr<blink::mojom::PresentationService> service_ptr_; | |
| 377 | 326 |
| 378 MockPresentationServiceClient mock_client_; | 327 MockPresentationServiceClient mock_client_; |
| 379 std::unique_ptr<mojo::Binding<blink::mojom::PresentationServiceClient>> | 328 std::unique_ptr<mojo::Binding<blink::mojom::PresentationServiceClient>> |
| 380 client_binding_; | 329 client_binding_; |
| 381 | 330 |
| 382 base::Closure run_loop_quit_closure_; | |
| 383 | |
| 384 GURL presentation_url1_; | 331 GURL presentation_url1_; |
| 385 GURL presentation_url2_; | 332 GURL presentation_url2_; |
| 386 GURL presentation_url3_; | 333 GURL presentation_url3_; |
| 387 std::vector<GURL> presentation_urls_; | 334 std::vector<GURL> presentation_urls_; |
| 388 }; | 335 }; |
| 389 | 336 |
| 390 TEST_F(PresentationServiceImplTest, ListenForScreenAvailability) { | 337 TEST_F(PresentationServiceImplTest, ListenForScreenAvailability) { |
| 391 ListenForScreenAvailabilityAndWait(presentation_url1_, true); | 338 ListenForScreenAvailabilityAndWait(presentation_url1_, true); |
| 392 | 339 |
| 393 SimulateScreenAvailabilityChangeAndWait(presentation_url1_, true); | 340 SimulateScreenAvailabilityChangeAndWait(presentation_url1_, true); |
| 394 SimulateScreenAvailabilityChangeAndWait(presentation_url1_, false); | 341 SimulateScreenAvailabilityChangeAndWait(presentation_url1_, false); |
| 395 SimulateScreenAvailabilityChangeAndWait(presentation_url1_, true); | 342 SimulateScreenAvailabilityChangeAndWait(presentation_url1_, true); |
| 396 } | 343 } |
| 397 | 344 |
| 345 TEST_F(PresentationServiceImplTest, ScreenAvailabilityNotSupported) { |
| 346 mock_delegate_.set_screen_availability_listening_supported(false); |
| 347 EXPECT_CALL(mock_client_, |
| 348 OnScreenAvailabilityNotSupported(presentation_url1_)); |
| 349 ListenForScreenAvailabilityAndWait(presentation_url1_, false); |
| 350 base::RunLoop().RunUntilIdle(); |
| 351 } |
| 352 |
| 398 TEST_F(PresentationServiceImplTest, Reset) { | 353 TEST_F(PresentationServiceImplTest, Reset) { |
| 399 ListenForScreenAvailabilityAndWait(presentation_url1_, true); | 354 ListenForScreenAvailabilityAndWait(presentation_url1_, true); |
| 400 | 355 |
| 401 ExpectReset(); | 356 ExpectReset(); |
| 402 service_impl_->Reset(); | 357 service_impl_->Reset(); |
| 403 ExpectCleanState(); | 358 ExpectCleanState(); |
| 404 } | 359 } |
| 405 | 360 |
| 406 TEST_F(PresentationServiceImplTest, DidNavigateThisFrame) { | 361 TEST_F(PresentationServiceImplTest, DidNavigateThisFrame) { |
| 407 ListenForScreenAvailabilityAndWait(presentation_url1_, true); | 362 ListenForScreenAvailabilityAndWait(presentation_url1_, true); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 422 } | 377 } |
| 423 | 378 |
| 424 TEST_F(PresentationServiceImplTest, ThisRenderFrameDeleted) { | 379 TEST_F(PresentationServiceImplTest, ThisRenderFrameDeleted) { |
| 425 ListenForScreenAvailabilityAndWait(presentation_url1_, true); | 380 ListenForScreenAvailabilityAndWait(presentation_url1_, true); |
| 426 | 381 |
| 427 ExpectReset(); | 382 ExpectReset(); |
| 428 | 383 |
| 429 // Since the frame matched the service, |service_impl_| will be deleted. | 384 // Since the frame matched the service, |service_impl_| will be deleted. |
| 430 PresentationServiceImpl* service = service_impl_.release(); | 385 PresentationServiceImpl* service = service_impl_.release(); |
| 431 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1); | 386 EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1); |
| 432 service->RenderFrameDeleted(contents()->GetMainFrame()); | 387 service->RenderFrameDeleted(main_rfh()); |
| 433 } | 388 } |
| 434 | 389 |
| 435 TEST_F(PresentationServiceImplTest, OtherRenderFrameDeleted) { | 390 TEST_F(PresentationServiceImplTest, OtherRenderFrameDeleted) { |
| 436 ListenForScreenAvailabilityAndWait(presentation_url1_, true); | 391 ListenForScreenAvailabilityAndWait(presentation_url1_, true); |
| 437 | 392 |
| 438 // TODO(imcheng): How to get a different RenderFrameHost? | 393 // Create a new frame and RFH. |
| 439 service_impl_->RenderFrameDeleted(nullptr); | 394 RenderFrameHost* rfh = main_rfh(); |
| 395 RenderFrameHostTester* rfh_tester = RenderFrameHostTester::For(rfh); |
| 396 rfh = rfh_tester->AppendChild("subframe"); |
| 397 service_impl_->RenderFrameDeleted(rfh); |
| 440 | 398 |
| 441 // Availability is reported and callback should be invoked since listener | 399 // Availability is reported and callback should be invoked since listener |
| 442 // has not been deleted. | 400 // has not been deleted. |
| 443 SimulateScreenAvailabilityChangeAndWait(presentation_url1_, true); | 401 SimulateScreenAvailabilityChangeAndWait(presentation_url1_, true); |
| 444 } | 402 } |
| 445 | 403 |
| 446 TEST_F(PresentationServiceImplTest, DelegateFails) { | 404 TEST_F(PresentationServiceImplTest, DelegateFails) { |
| 447 ListenForScreenAvailabilityAndWait(presentation_url1_, false); | 405 ListenForScreenAvailabilityAndWait(presentation_url1_, false); |
| 448 ASSERT_EQ( | 406 ASSERT_EQ( |
| 449 service_impl_->screen_availability_listeners_.find(presentation_url1_), | 407 service_impl_->screen_availability_listeners_.end(), |
| 450 service_impl_->screen_availability_listeners_.end()); | 408 service_impl_->screen_availability_listeners_.find(presentation_url1_)); |
| 451 } | 409 } |
| 452 | 410 |
| 453 TEST_F(PresentationServiceImplTest, SetDefaultPresentationUrls) { | 411 TEST_F(PresentationServiceImplTest, SetDefaultPresentationUrls) { |
| 454 EXPECT_CALL(mock_delegate_, | 412 EXPECT_CALL(mock_delegate_, |
| 455 SetDefaultPresentationUrls(_, _, presentation_urls_, _)) | 413 SetDefaultPresentationUrls(_, _, presentation_urls_, _)) |
| 456 .Times(1); | 414 .Times(1); |
| 457 | 415 |
| 458 service_impl_->SetDefaultPresentationUrls(presentation_urls_); | 416 service_impl_->SetDefaultPresentationUrls(presentation_urls_); |
| 459 | 417 |
| 460 // Sets different DPUs. | 418 // Sets different DPUs. |
| 461 std::vector<GURL> more_urls = presentation_urls_; | 419 std::vector<GURL> more_urls = presentation_urls_; |
| 462 more_urls.push_back(presentation_url3_); | 420 more_urls.push_back(presentation_url3_); |
| 463 | 421 |
| 464 PresentationConnectionCallback callback; | 422 PresentationConnectionCallback callback; |
| 465 EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(_, _, more_urls, _)) | 423 EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrls(_, _, more_urls, _)) |
| 466 .WillOnce(SaveArg<3>(&callback)); | 424 .WillOnce(SaveArg<3>(&callback)); |
| 467 service_impl_->SetDefaultPresentationUrls(more_urls); | 425 service_impl_->SetDefaultPresentationUrls(more_urls); |
| 468 | 426 |
| 469 PresentationInfo presentation_info(presentation_url2_, kPresentationId); | 427 PresentationInfo presentation_info(presentation_url2_, kPresentationId); |
| 470 | 428 |
| 471 base::RunLoop run_loop; | |
| 472 EXPECT_CALL(mock_client_, | 429 EXPECT_CALL(mock_client_, |
| 473 OnDefaultPresentationStarted(InfoEquals(presentation_info))) | 430 OnDefaultPresentationStarted(InfoEquals(presentation_info))); |
| 474 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | |
| 475 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)); | 431 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)); |
| 476 callback.Run(PresentationInfo(presentation_url2_, kPresentationId)); | 432 callback.Run(PresentationInfo(presentation_url2_, kPresentationId)); |
| 477 run_loop.Run(); | 433 base::RunLoop().RunUntilIdle(); |
| 478 } | 434 } |
| 479 | 435 |
| 480 TEST_F(PresentationServiceImplTest, ListenForConnectionStateChange) { | 436 TEST_F(PresentationServiceImplTest, ListenForConnectionStateChange) { |
| 481 PresentationInfo connection(presentation_url1_, kPresentationId); | 437 PresentationInfo connection(presentation_url1_, kPresentationId); |
| 482 PresentationConnectionStateChangedCallback state_changed_cb; | 438 PresentationConnectionStateChangedCallback state_changed_cb; |
| 483 // Trigger state change. It should be propagated back up to |mock_client_|. | 439 // Trigger state change. It should be propagated back up to |mock_client_|. |
| 484 PresentationInfo presentation_connection(presentation_url1_, kPresentationId); | 440 PresentationInfo presentation_connection(presentation_url1_, kPresentationId); |
| 485 | 441 |
| 486 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) | 442 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) |
| 487 .WillOnce(SaveArg<3>(&state_changed_cb)); | 443 .WillOnce(SaveArg<3>(&state_changed_cb)); |
| 488 service_impl_->ListenForConnectionStateChange(connection); | 444 service_impl_->ListenForConnectionStateChange(connection); |
| 489 | 445 |
| 490 { | 446 EXPECT_CALL(mock_client_, OnConnectionStateChanged( |
| 491 base::RunLoop run_loop; | 447 InfoEquals(presentation_connection), |
| 492 EXPECT_CALL(mock_client_, OnConnectionStateChanged( | 448 PRESENTATION_CONNECTION_STATE_TERMINATED)); |
| 493 InfoEquals(presentation_connection), | 449 state_changed_cb.Run(PresentationConnectionStateChangeInfo( |
| 494 PRESENTATION_CONNECTION_STATE_TERMINATED)) | 450 PRESENTATION_CONNECTION_STATE_TERMINATED)); |
| 495 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | 451 base::RunLoop().RunUntilIdle(); |
| 496 state_changed_cb.Run(PresentationConnectionStateChangeInfo( | |
| 497 PRESENTATION_CONNECTION_STATE_TERMINATED)); | |
| 498 run_loop.Run(); | |
| 499 } | |
| 500 } | 452 } |
| 501 | 453 |
| 502 TEST_F(PresentationServiceImplTest, ListenForConnectionClose) { | 454 TEST_F(PresentationServiceImplTest, ListenForConnectionClose) { |
| 503 PresentationInfo connection(presentation_url1_, kPresentationId); | 455 PresentationInfo connection(presentation_url1_, kPresentationId); |
| 504 PresentationConnectionStateChangedCallback state_changed_cb; | 456 PresentationConnectionStateChangedCallback state_changed_cb; |
| 505 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) | 457 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) |
| 506 .WillOnce(SaveArg<3>(&state_changed_cb)); | 458 .WillOnce(SaveArg<3>(&state_changed_cb)); |
| 507 service_impl_->ListenForConnectionStateChange(connection); | 459 service_impl_->ListenForConnectionStateChange(connection); |
| 508 | 460 |
| 509 // Trigger connection close. It should be propagated back up to | 461 // Trigger connection close. It should be propagated back up to |
| 510 // |mock_client_|. | 462 // |mock_client_|. |
| 511 PresentationInfo presentation_connection(presentation_url1_, kPresentationId); | 463 PresentationInfo presentation_connection(presentation_url1_, kPresentationId); |
| 512 { | 464 PresentationConnectionStateChangeInfo closed_info( |
| 513 base::RunLoop run_loop; | 465 PRESENTATION_CONNECTION_STATE_CLOSED); |
| 514 PresentationConnectionStateChangeInfo closed_info( | 466 closed_info.close_reason = PRESENTATION_CONNECTION_CLOSE_REASON_WENT_AWAY; |
| 515 PRESENTATION_CONNECTION_STATE_CLOSED); | 467 closed_info.message = "Foo"; |
| 516 closed_info.close_reason = PRESENTATION_CONNECTION_CLOSE_REASON_WENT_AWAY; | |
| 517 closed_info.message = "Foo"; | |
| 518 | 468 |
| 519 EXPECT_CALL(mock_client_, | 469 EXPECT_CALL(mock_client_, |
| 520 OnConnectionClosed( | 470 OnConnectionClosed(InfoEquals(presentation_connection), |
| 521 InfoEquals(presentation_connection), | 471 PRESENTATION_CONNECTION_CLOSE_REASON_WENT_AWAY, |
| 522 PRESENTATION_CONNECTION_CLOSE_REASON_WENT_AWAY, "Foo")) | 472 "Foo")); |
| 523 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | 473 state_changed_cb.Run(closed_info); |
| 524 state_changed_cb.Run(closed_info); | 474 base::RunLoop().RunUntilIdle(); |
| 525 run_loop.Run(); | |
| 526 } | |
| 527 } | 475 } |
| 528 | 476 |
| 529 TEST_F(PresentationServiceImplTest, SetSameDefaultPresentationUrls) { | 477 TEST_F(PresentationServiceImplTest, SetSameDefaultPresentationUrls) { |
| 530 EXPECT_CALL(mock_delegate_, | 478 EXPECT_CALL(mock_delegate_, |
| 531 SetDefaultPresentationUrls(_, _, presentation_urls_, _)) | 479 SetDefaultPresentationUrls(_, _, presentation_urls_, _)) |
| 532 .Times(1); | 480 .Times(1); |
| 533 service_impl_->SetDefaultPresentationUrls(presentation_urls_); | 481 service_impl_->SetDefaultPresentationUrls(presentation_urls_); |
| 534 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_)); | 482 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_)); |
| 535 | 483 |
| 536 // Same URLs as before; no-ops. | 484 // Same URLs as before; no-ops. |
| 537 service_impl_->SetDefaultPresentationUrls(presentation_urls_); | 485 service_impl_->SetDefaultPresentationUrls(presentation_urls_); |
| 538 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_)); | 486 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_)); |
| 539 } | 487 } |
| 540 | 488 |
| 541 TEST_F(PresentationServiceImplTest, StartPresentationSuccess) { | 489 TEST_F(PresentationServiceImplTest, StartPresentationSuccess) { |
| 542 service_ptr_->StartPresentation( | 490 base::MockCallback<NewPresentationCallback> mock_presentation_cb; |
| 543 presentation_urls_, | |
| 544 base::Bind( | |
| 545 &PresentationServiceImplTest::ExpectNewPresentationCallbackSuccess, | |
| 546 base::Unretained(this))); | |
| 547 base::RunLoop run_loop; | |
| 548 base::Callback<void(const PresentationInfo&)> success_cb; | 491 base::Callback<void(const PresentationInfo&)> success_cb; |
| 549 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) | 492 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) |
| 550 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit), | 493 .WillOnce(SaveArg<3>(&success_cb)); |
| 551 SaveArg<3>(&success_cb))); | 494 service_impl_->StartPresentation(presentation_urls_, |
| 552 run_loop.Run(); | 495 mock_presentation_cb.Get()); |
| 553 | 496 EXPECT_FALSE(success_cb.is_null()); |
| 554 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) | 497 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) |
| 555 .Times(1); | 498 .Times(1); |
| 499 EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNotNull(), OptionalIsNull())); |
| 556 success_cb.Run(PresentationInfo(presentation_url1_, kPresentationId)); | 500 success_cb.Run(PresentationInfo(presentation_url1_, kPresentationId)); |
| 557 SaveQuitClosureAndRunLoop(); | |
| 558 } | 501 } |
| 559 | 502 |
| 560 TEST_F(PresentationServiceImplTest, StartPresentationError) { | 503 TEST_F(PresentationServiceImplTest, StartPresentationError) { |
| 561 service_ptr_->StartPresentation( | 504 base::MockCallback<NewPresentationCallback> mock_presentation_cb; |
| 562 presentation_urls_, | |
| 563 base::Bind( | |
| 564 &PresentationServiceImplTest::ExpectNewPresentationCallbackError, | |
| 565 base::Unretained(this))); | |
| 566 base::RunLoop run_loop; | |
| 567 base::Callback<void(const PresentationError&)> error_cb; | 505 base::Callback<void(const PresentationError&)> error_cb; |
| 568 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) | 506 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) |
| 569 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit), | 507 .WillOnce(SaveArg<4>(&error_cb)); |
| 570 SaveArg<4>(&error_cb))); | 508 service_impl_->StartPresentation(presentation_urls_, |
| 571 run_loop.Run(); | 509 mock_presentation_cb.Get()); |
| 510 EXPECT_FALSE(error_cb.is_null()); |
| 511 EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNull(), OptionalIsNotNull())); |
| 572 error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message")); | 512 error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message")); |
| 573 SaveQuitClosureAndRunLoop(); | 513 } |
| 514 |
| 515 TEST_F(PresentationServiceImplTest, StartPresentationInProgress) { |
| 516 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) |
| 517 .Times(1); |
| 518 // Uninvoked callbacks must outlive |service_impl_| since they get invoked |
| 519 // at |service_impl_|'s destruction. |
| 520 service_impl_->StartPresentation(presentation_urls_, base::Bind(&DoNothing)); |
| 521 |
| 522 // This request should fail immediately, since there is already a |
| 523 // StartPresentation in progress. |
| 524 base::MockCallback<NewPresentationCallback> mock_presentation_cb; |
| 525 EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNull(), OptionalIsNotNull())); |
| 526 service_impl_->StartPresentation(presentation_urls_, |
| 527 mock_presentation_cb.Get()); |
| 574 } | 528 } |
| 575 | 529 |
| 576 TEST_F(PresentationServiceImplTest, ReconnectPresentationSuccess) { | 530 TEST_F(PresentationServiceImplTest, ReconnectPresentationSuccess) { |
| 577 service_ptr_->ReconnectPresentation( | 531 base::MockCallback<NewPresentationCallback> mock_presentation_cb; |
| 578 presentation_urls_, base::Optional<std::string>(kPresentationId), | |
| 579 base::Bind( | |
| 580 &PresentationServiceImplTest::ExpectNewPresentationCallbackSuccess, | |
| 581 base::Unretained(this))); | |
| 582 base::RunLoop run_loop; | |
| 583 base::Callback<void(const PresentationInfo&)> success_cb; | 532 base::Callback<void(const PresentationInfo&)> success_cb; |
| 584 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, presentation_urls_, | 533 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, presentation_urls_, |
| 585 kPresentationId, _, _)) | 534 kPresentationId, _, _)) |
| 586 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit), | 535 .WillOnce(SaveArg<4>(&success_cb)); |
| 587 SaveArg<4>(&success_cb))); | 536 service_impl_->ReconnectPresentation( |
| 588 run_loop.Run(); | 537 presentation_urls_, base::Optional<std::string>(kPresentationId), |
| 589 | 538 mock_presentation_cb.Get()); |
| 539 EXPECT_FALSE(success_cb.is_null()); |
| 590 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) | 540 EXPECT_CALL(mock_delegate_, ListenForConnectionStateChange(_, _, _, _)) |
| 591 .Times(1); | 541 .Times(1); |
| 542 EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNotNull(), OptionalIsNull())); |
| 592 success_cb.Run(PresentationInfo(presentation_url1_, kPresentationId)); | 543 success_cb.Run(PresentationInfo(presentation_url1_, kPresentationId)); |
| 593 SaveQuitClosureAndRunLoop(); | |
| 594 } | 544 } |
| 595 | 545 |
| 596 TEST_F(PresentationServiceImplTest, ReconnectPresentationError) { | 546 TEST_F(PresentationServiceImplTest, ReconnectPresentationError) { |
| 597 service_ptr_->ReconnectPresentation( | 547 base::MockCallback<NewPresentationCallback> mock_presentation_cb; |
| 598 presentation_urls_, base::Optional<std::string>(kPresentationId), | |
| 599 base::Bind( | |
| 600 &PresentationServiceImplTest::ExpectNewPresentationCallbackError, | |
| 601 base::Unretained(this))); | |
| 602 base::RunLoop run_loop; | |
| 603 base::Callback<void(const PresentationError&)> error_cb; | 548 base::Callback<void(const PresentationError&)> error_cb; |
| 604 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, presentation_urls_, | 549 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, presentation_urls_, |
| 605 kPresentationId, _, _)) | 550 kPresentationId, _, _)) |
| 606 .WillOnce(DoAll(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit), | 551 .WillOnce(SaveArg<5>(&error_cb)); |
| 607 SaveArg<5>(&error_cb))); | 552 service_impl_->ReconnectPresentation( |
| 608 run_loop.Run(); | 553 presentation_urls_, base::Optional<std::string>(kPresentationId), |
| 554 mock_presentation_cb.Get()); |
| 555 EXPECT_FALSE(error_cb.is_null()); |
| 556 EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNull(), OptionalIsNotNull())); |
| 609 error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message")); | 557 error_cb.Run(PresentationError(PRESENTATION_ERROR_UNKNOWN, "Error message")); |
| 610 SaveQuitClosureAndRunLoop(); | 558 } |
| 559 |
| 560 TEST_F(PresentationServiceImplTest, MaxPendingReconnectPresentationRequests) { |
| 561 const char* presentation_url = "http://fooUrl%d"; |
| 562 const char* presentation_id = "presentationId%d"; |
| 563 int num_requests = PresentationServiceImpl::kMaxQueuedRequests; |
| 564 int i = 0; |
| 565 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, _, _, _, _)) |
| 566 .Times(num_requests); |
| 567 for (; i < num_requests; ++i) { |
| 568 std::vector<GURL> urls = {GURL(base::StringPrintf(presentation_url, i))}; |
| 569 // Uninvoked callbacks must outlive |service_impl_| since they get invoked |
| 570 // at |service_impl_|'s destruction. |
| 571 service_impl_->ReconnectPresentation( |
| 572 urls, base::StringPrintf(presentation_id, i), base::Bind(&DoNothing)); |
| 573 } |
| 574 |
| 575 std::vector<GURL> urls = {GURL(base::StringPrintf(presentation_url, i))}; |
| 576 // Exceeded maximum queue size, should invoke mojo callback with error. |
| 577 base::MockCallback<NewPresentationCallback> mock_presentation_cb; |
| 578 EXPECT_CALL(mock_presentation_cb, Run(OptionalIsNull(), OptionalIsNotNull())); |
| 579 service_impl_->ReconnectPresentation( |
| 580 urls, base::StringPrintf(presentation_id, i), mock_presentation_cb.Get()); |
| 611 } | 581 } |
| 612 | 582 |
| 613 TEST_F(PresentationServiceImplTest, CloseConnection) { | 583 TEST_F(PresentationServiceImplTest, CloseConnection) { |
| 614 service_ptr_->CloseConnection(presentation_url1_, kPresentationId); | 584 EXPECT_CALL(mock_delegate_, CloseConnection(_, _, Eq(kPresentationId))); |
| 615 | 585 service_impl_->CloseConnection(presentation_url1_, kPresentationId); |
| 616 base::RunLoop run_loop; | |
| 617 EXPECT_CALL(mock_delegate_, CloseConnection(_, _, Eq(kPresentationId))) | |
| 618 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | |
| 619 run_loop.Run(); | |
| 620 } | 586 } |
| 621 | 587 |
| 622 TEST_F(PresentationServiceImplTest, Terminate) { | 588 TEST_F(PresentationServiceImplTest, Terminate) { |
| 623 service_ptr_->Terminate(presentation_url1_, kPresentationId); | 589 EXPECT_CALL(mock_delegate_, Terminate(_, _, Eq(kPresentationId))); |
| 624 base::RunLoop run_loop; | 590 service_impl_->Terminate(presentation_url1_, kPresentationId); |
| 625 EXPECT_CALL(mock_delegate_, Terminate(_, _, Eq(kPresentationId))) | |
| 626 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | |
| 627 run_loop.Run(); | |
| 628 } | 591 } |
| 629 | 592 |
| 630 TEST_F(PresentationServiceImplTest, SetPresentationConnection) { | 593 TEST_F(PresentationServiceImplTest, SetPresentationConnection) { |
| 631 PresentationInfo presentation_info(presentation_url1_, kPresentationId); | 594 PresentationInfo presentation_info(presentation_url1_, kPresentationId); |
| 632 | 595 |
| 633 blink::mojom::PresentationConnectionPtr connection; | 596 blink::mojom::PresentationConnectionPtr connection; |
| 634 MockPresentationConnection mock_presentation_connection; | 597 MockPresentationConnection mock_presentation_connection; |
| 635 mojo::Binding<blink::mojom::PresentationConnection> connection_binding( | 598 mojo::Binding<blink::mojom::PresentationConnection> connection_binding( |
| 636 &mock_presentation_connection, mojo::MakeRequest(&connection)); | 599 &mock_presentation_connection, mojo::MakeRequest(&connection)); |
| 637 blink::mojom::PresentationConnectionPtr receiver_connection; | 600 blink::mojom::PresentationConnectionPtr receiver_connection; |
| 638 auto request = mojo::MakeRequest(&receiver_connection); | 601 auto request = mojo::MakeRequest(&receiver_connection); |
| 639 | 602 |
| 640 PresentationInfo expected(presentation_url1_, kPresentationId); | 603 PresentationInfo expected(presentation_url1_, kPresentationId); |
| 641 EXPECT_CALL(mock_delegate_, RegisterOffscreenPresentationConnectionRaw( | 604 EXPECT_CALL(mock_delegate_, RegisterOffscreenPresentationConnectionRaw( |
| 642 _, _, InfoEquals(expected), _)); | 605 _, _, InfoEquals(expected), _)); |
| 643 | 606 |
| 644 service_impl_->SetPresentationConnection( | 607 service_impl_->SetPresentationConnection( |
| 645 presentation_info, std::move(connection), std::move(request)); | 608 presentation_info, std::move(connection), std::move(request)); |
| 646 } | 609 } |
| 647 | 610 |
| 648 TEST_F(PresentationServiceImplTest, ReceiverPresentationServiceDelegate) { | 611 TEST_F(PresentationServiceImplTest, ReceiverPresentationServiceDelegate) { |
| 649 MockReceiverPresentationServiceDelegate mock_receiver_delegate; | 612 MockReceiverPresentationServiceDelegate mock_receiver_delegate; |
| 613 EXPECT_CALL(mock_receiver_delegate, AddObserver(_, _, _)).Times(1); |
| 650 | 614 |
| 651 PresentationServiceImpl service_impl(contents()->GetMainFrame(), contents(), | 615 PresentationServiceImpl service_impl(main_rfh(), contents(), nullptr, |
| 652 nullptr, &mock_receiver_delegate); | 616 &mock_receiver_delegate); |
| 653 | 617 |
| 654 ReceiverConnectionAvailableCallback callback; | 618 ReceiverConnectionAvailableCallback callback; |
| 655 EXPECT_CALL(mock_receiver_delegate, | 619 EXPECT_CALL(mock_receiver_delegate, |
| 656 RegisterReceiverConnectionAvailableCallback(_)) | 620 RegisterReceiverConnectionAvailableCallback(_)) |
| 657 .WillOnce(SaveArg<0>(&callback)); | 621 .WillOnce(SaveArg<0>(&callback)); |
| 658 | 622 |
| 659 blink::mojom::PresentationServiceClientPtr client_ptr; | 623 blink::mojom::PresentationServiceClientPtr client_ptr; |
| 660 client_binding_.reset( | 624 client_binding_.reset( |
| 661 new mojo::Binding<blink::mojom::PresentationServiceClient>( | 625 new mojo::Binding<blink::mojom::PresentationServiceClient>( |
| 662 &mock_client_, mojo::MakeRequest(&client_ptr))); | 626 &mock_client_, mojo::MakeRequest(&client_ptr))); |
| 663 service_impl.controller_delegate_ = nullptr; | 627 service_impl.controller_delegate_ = nullptr; |
| 664 service_impl.SetClient(std::move(client_ptr)); | 628 service_impl.SetClient(std::move(client_ptr)); |
| 665 EXPECT_FALSE(callback.is_null()); | 629 EXPECT_FALSE(callback.is_null()); |
| 666 | 630 |
| 667 // NO-OP for ControllerPresentationServiceDelegate API functions | 631 // NO-OP for ControllerPresentationServiceDelegate API functions |
| 632 PresentationInfo presentation_info(presentation_url1_, kPresentationId); |
| 668 EXPECT_CALL(mock_delegate_, ListenForConnectionMessages(_, _, _, _)).Times(0); | 633 EXPECT_CALL(mock_delegate_, ListenForConnectionMessages(_, _, _, _)).Times(0); |
| 634 service_impl.ListenForConnectionMessages(presentation_info); |
| 669 | 635 |
| 670 PresentationInfo presentation_info(presentation_url1_, kPresentationId); | 636 // Client gets notified of receiver connections. |
| 671 service_impl.ListenForConnectionMessages(presentation_info); | 637 blink::mojom::PresentationConnectionPtr controller_connection; |
| 672 } | 638 MockPresentationConnection mock_presentation_connection; |
| 639 mojo::Binding<blink::mojom::PresentationConnection> connection_binding( |
| 640 &mock_presentation_connection, mojo::MakeRequest(&controller_connection)); |
| 641 blink::mojom::PresentationConnectionPtr receiver_connection; |
| 642 EXPECT_CALL(mock_client_, |
| 643 OnReceiverConnectionAvailable(InfoEquals(presentation_info))); |
| 644 callback.Run(presentation_info, std::move(controller_connection), |
| 645 mojo::MakeRequest(&receiver_connection)); |
| 646 base::RunLoop().RunUntilIdle(); |
| 673 | 647 |
| 674 TEST_F(PresentationServiceImplTest, StartPresentationInProgress) { | 648 EXPECT_CALL(mock_receiver_delegate, RemoveObserver(_, _)).Times(1); |
| 675 EXPECT_CALL(mock_delegate_, StartPresentation(_, _, presentation_urls_, _, _)) | |
| 676 .Times(1); | |
| 677 service_ptr_->StartPresentation(presentation_urls_, base::Bind(&DoNothing)); | |
| 678 | |
| 679 // This request should fail immediately, since there is already a | |
| 680 // StartPresentation in progress. | |
| 681 service_ptr_->StartPresentation( | |
| 682 presentation_urls_, | |
| 683 base::Bind( | |
| 684 &PresentationServiceImplTest::ExpectNewPresentationCallbackError, | |
| 685 base::Unretained(this))); | |
| 686 SaveQuitClosureAndRunLoop(); | |
| 687 } | |
| 688 | |
| 689 TEST_F(PresentationServiceImplTest, MaxPendingReconnectPresentationRequests) { | |
| 690 const char* presentation_url = "http://fooUrl%d"; | |
| 691 const char* presentation_id = "presentationId%d"; | |
| 692 int num_requests = PresentationServiceImpl::kMaxQueuedRequests; | |
| 693 int i = 0; | |
| 694 EXPECT_CALL(mock_delegate_, ReconnectPresentation(_, _, _, _, _, _)) | |
| 695 .Times(num_requests); | |
| 696 for (; i < num_requests; ++i) { | |
| 697 std::vector<GURL> urls = {GURL(base::StringPrintf(presentation_url, i))}; | |
| 698 service_ptr_->ReconnectPresentation( | |
| 699 urls, base::StringPrintf(presentation_id, i), base::Bind(&DoNothing)); | |
| 700 } | |
| 701 | |
| 702 std::vector<GURL> urls = {GURL(base::StringPrintf(presentation_url, i))}; | |
| 703 // Exceeded maximum queue size, should invoke mojo callback with error. | |
| 704 service_ptr_->ReconnectPresentation( | |
| 705 urls, base::StringPrintf(presentation_id, i), | |
| 706 base::Bind( | |
| 707 &PresentationServiceImplTest::ExpectNewPresentationCallbackError, | |
| 708 base::Unretained(this))); | |
| 709 SaveQuitClosureAndRunLoop(); | |
| 710 } | |
| 711 | |
| 712 TEST_F(PresentationServiceImplTest, ScreenAvailabilityNotSupported) { | |
| 713 mock_delegate_.set_screen_availability_listening_supported(false); | |
| 714 base::RunLoop run_loop; | |
| 715 EXPECT_CALL(mock_client_, | |
| 716 OnScreenAvailabilityNotSupported(presentation_url1_)) | |
| 717 .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); | |
| 718 ListenForScreenAvailabilityAndWait(presentation_url1_, false); | |
| 719 run_loop.Run(); | |
| 720 } | 649 } |
| 721 | 650 |
| 722 } // namespace content | 651 } // namespace content |
| OLD | NEW |