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

Side by Side Diff: content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc

Issue 14197014: Add TestBrowserThreadBundle into RenderViewHostTestHarness. Kill some unnecessary real threads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merged ToT Created 7 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/renderer_host/media/web_contents_video_capture_device. h" 5 #include "content/browser/renderer_host/media/web_contents_video_capture_device. h"
6 6
7 #include "base/bind_helpers.h" 7 #include "base/bind_helpers.h"
8 #include "base/debug/debugger.h" 8 #include "base/debug/debugger.h"
9 #include "base/run_loop.h" 9 #include "base/run_loop.h"
10 #include "base/test/test_timeouts.h" 10 #include "base/test/test_timeouts.h"
11 #include "base/time.h" 11 #include "base/time.h"
12 #include "base/timer.h" 12 #include "base/timer.h"
13 #include "content/browser/browser_thread_impl.h" 13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" 14 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
15 #include "content/browser/renderer_host/media/video_capture_oracle.h" 15 #include "content/browser/renderer_host/media/video_capture_oracle.h"
16 #include "content/browser/renderer_host/media/web_contents_capture_util.h" 16 #include "content/browser/renderer_host/media/web_contents_capture_util.h"
17 #include "content/browser/renderer_host/render_view_host_factory.h" 17 #include "content/browser/renderer_host/render_view_host_factory.h"
18 #include "content/browser/renderer_host/render_widget_host_impl.h" 18 #include "content/browser/renderer_host/render_widget_host_impl.h"
19 #include "content/browser/renderer_host/test_render_view_host.h" 19 #include "content/browser/renderer_host/test_render_view_host.h"
20 #include "content/port/browser/render_widget_host_view_frame_subscriber.h" 20 #include "content/port/browser/render_widget_host_view_frame_subscriber.h"
21 #include "content/public/browser/notification_service.h" 21 #include "content/public/browser/notification_service.h"
22 #include "content/public/browser/notification_types.h" 22 #include "content/public/browser/notification_types.h"
23 #include "content/public/test/mock_render_process_host.h" 23 #include "content/public/test/mock_render_process_host.h"
24 #include "content/public/test/test_browser_context.h" 24 #include "content/public/test/test_browser_context.h"
25 #include "content/public/test/test_browser_thread.h" 25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "content/public/test/test_utils.h" 26 #include "content/public/test/test_utils.h"
27 #include "content/test/test_web_contents.h" 27 #include "content/test/test_web_contents.h"
28 #include "media/base/video_util.h" 28 #include "media/base/video_util.h"
29 #include "media/base/yuv_convert.h" 29 #include "media/base/yuv_convert.h"
30 #include "media/video/capture/video_capture_types.h" 30 #include "media/video/capture/video_capture_types.h"
31 #include "skia/ext/platform_canvas.h" 31 #include "skia/ext/platform_canvas.h"
32 #include "testing/gtest/include/gtest/gtest.h" 32 #include "testing/gtest/include/gtest/gtest.h"
33 #include "third_party/skia/include/core/SkColor.h" 33 #include "third_party/skia/include/core/SkColor.h"
34 34
35 namespace content { 35 namespace content {
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
410 bool error_encountered_; 410 bool error_encountered_;
411 SkColor wait_color_yuv_; 411 SkColor wait_color_yuv_;
412 scoped_refptr<VideoCaptureBufferPool> buffer_pool_; 412 scoped_refptr<VideoCaptureBufferPool> buffer_pool_;
413 413
414 DISALLOW_COPY_AND_ASSIGN(StubConsumer); 414 DISALLOW_COPY_AND_ASSIGN(StubConsumer);
415 }; 415 };
416 416
417 // Test harness that sets up a minimal environment with necessary stubs. 417 // Test harness that sets up a minimal environment with necessary stubs.
418 class WebContentsVideoCaptureDeviceTest : public testing::Test { 418 class WebContentsVideoCaptureDeviceTest : public testing::Test {
419 public: 419 public:
420 WebContentsVideoCaptureDeviceTest() {} 420 // This is public because C++ method pointer scoping rules are silly and make
421 421 // this hard to use with Bind().
422 void ResetWebContents() { 422 void ResetWebContents() {
423 web_contents_.reset(); 423 web_contents_.reset();
424 } 424 }
425 425
426 protected: 426 protected:
427 virtual void SetUp() { 427 virtual void SetUp() {
428 // TODO(nick): Sadness and woe! Much "mock-the-world" boilerplate could be 428 // TODO(nick): Sadness and woe! Much "mock-the-world" boilerplate could be
429 // eliminated here, if only we could use RenderViewHostTestHarness. The 429 // eliminated here, if only we could use RenderViewHostTestHarness. The
430 // catch is that we need our TestRenderViewHost to support a 430 // catch is that we need our TestRenderViewHost to support a
431 // CopyFromBackingStore operation that we control. To accomplish that, 431 // CopyFromBackingStore operation that we control. To accomplish that,
432 // either RenderViewHostTestHarness would have to support installing a 432 // either RenderViewHostTestHarness would have to support installing a
433 // custom RenderViewHostFactory, or else we implant some kind of delegated 433 // custom RenderViewHostFactory, or else we implant some kind of delegated
434 // CopyFromBackingStore functionality into TestRenderViewHost itself. 434 // CopyFromBackingStore functionality into TestRenderViewHost itself.
435 435
436 // The main thread will serve as the UI thread as well as the test thread.
437 // We'll manually pump the run loop at appropriate times in the test.
438 ui_thread_.reset(new TestBrowserThread(BrowserThread::UI, &message_loop_));
439
440 render_process_host_factory_.reset(new MockRenderProcessHostFactory()); 436 render_process_host_factory_.reset(new MockRenderProcessHostFactory());
441 // Create our (self-registering) RVH factory, so that when we create a 437 // Create our (self-registering) RVH factory, so that when we create a
442 // WebContents, it in turn creates CaptureTestRenderViewHosts. 438 // WebContents, it in turn creates CaptureTestRenderViewHosts.
443 render_view_host_factory_.reset( 439 render_view_host_factory_.reset(
444 new CaptureTestRenderViewHostFactory(&controller_)); 440 new CaptureTestRenderViewHostFactory(&controller_));
445 441
446 browser_context_.reset(new TestBrowserContext()); 442 browser_context_.reset(new TestBrowserContext());
447 443
448 scoped_refptr<SiteInstance> site_instance = 444 scoped_refptr<SiteInstance> site_instance =
449 SiteInstance::Create(browser_context_.get()); 445 SiteInstance::Create(browser_context_.get());
450 SiteInstanceImpl::set_render_process_host_factory( 446 SiteInstanceImpl::set_render_process_host_factory(
451 render_process_host_factory_.get()); 447 render_process_host_factory_.get());
452 web_contents_.reset( 448 web_contents_.reset(
453 TestWebContents::Create(browser_context_.get(), site_instance.get())); 449 TestWebContents::Create(browser_context_.get(), site_instance.get()));
454 450
455 // This is actually a CaptureTestRenderViewHost. 451 // This is actually a CaptureTestRenderViewHost.
456 RenderWidgetHostImpl* rwh = 452 RenderWidgetHostImpl* rwh =
457 RenderWidgetHostImpl::From(web_contents_->GetRenderViewHost()); 453 RenderWidgetHostImpl::From(web_contents_->GetRenderViewHost());
458 454
459 std::string device_id = 455 std::string device_id =
460 WebContentsCaptureUtil::AppendWebContentsDeviceScheme( 456 WebContentsCaptureUtil::AppendWebContentsDeviceScheme(
461 base::StringPrintf("%d:%d", rwh->GetProcess()->GetID(), 457 base::StringPrintf("%d:%d", rwh->GetProcess()->GetID(),
462 rwh->GetRoutingID())); 458 rwh->GetRoutingID()));
463 459
464 device_.reset(WebContentsVideoCaptureDevice::Create(device_id)); 460 device_.reset(WebContentsVideoCaptureDevice::Create(device_id));
465 461
466 content::RunAllPendingInMessageLoop(); 462 base::RunLoop().RunUntilIdle();
467 } 463 }
468 464
469 virtual void TearDown() { 465 virtual void TearDown() {
470 // Tear down in opposite order of set-up. 466 // Tear down in opposite order of set-up.
471 467
472 // The device is destroyed asynchronously, and will notify the 468 // The device is destroyed asynchronously, and will notify the
473 // CaptureTestSourceController when it finishes destruction. 469 // CaptureTestSourceController when it finishes destruction.
474 // Trigger this, and wait. 470 // Trigger this, and wait.
475 if (device_) { 471 if (device_) {
476 device_->DeAllocate(); 472 device_->DeAllocate();
477 device_.reset(); 473 device_.reset();
478 } 474 }
479 475
480 content::RunAllPendingInMessageLoop(); 476 base::RunLoop().RunUntilIdle();
481 477
482 // Destroy the browser objects. 478 // Destroy the browser objects.
483 web_contents_.reset(); 479 web_contents_.reset();
484 browser_context_.reset(); 480 browser_context_.reset();
485 481
486 content::RunAllPendingInMessageLoop(); 482 base::RunLoop().RunUntilIdle();
487 483
488 SiteInstanceImpl::set_render_process_host_factory(NULL); 484 SiteInstanceImpl::set_render_process_host_factory(NULL);
489 render_view_host_factory_.reset(); 485 render_view_host_factory_.reset();
490 render_process_host_factory_.reset(); 486 render_process_host_factory_.reset();
491 } 487 }
492 488
493 // Accessors. 489 // Accessors.
494 CaptureTestSourceController* source() { return &controller_; } 490 CaptureTestSourceController* source() { return &controller_; }
495 media::VideoCaptureDevice* device() { return device_.get(); } 491 media::VideoCaptureDevice* device() { return device_.get(); }
496 StubConsumer* consumer() { return &consumer_; } 492 StubConsumer* consumer() { return &consumer_; }
(...skipping 15 matching lines...) Expand all
512 508
513 void DestroyVideoCaptureDevice() { device_.reset(); } 509 void DestroyVideoCaptureDevice() { device_.reset(); }
514 510
515 private: 511 private:
516 // The consumer is the ultimate recipient of captured pixel data. 512 // The consumer is the ultimate recipient of captured pixel data.
517 StubConsumer consumer_; 513 StubConsumer consumer_;
518 514
519 // The controller controls which pixel patterns to produce. 515 // The controller controls which pixel patterns to produce.
520 CaptureTestSourceController controller_; 516 CaptureTestSourceController controller_;
521 517
522 // We run the UI message loop on the main thread. The capture device
523 // will also spin up its own threads.
524 base::MessageLoopForUI message_loop_;
525 scoped_ptr<TestBrowserThread> ui_thread_;
526
527 // Self-registering RenderProcessHostFactory. 518 // Self-registering RenderProcessHostFactory.
528 scoped_ptr<MockRenderProcessHostFactory> render_process_host_factory_; 519 scoped_ptr<MockRenderProcessHostFactory> render_process_host_factory_;
529 520
530 // Creates capture-capable RenderViewHosts whose pixel content production is 521 // Creates capture-capable RenderViewHosts whose pixel content production is
531 // under the control of |controller_|. 522 // under the control of |controller_|.
532 scoped_ptr<CaptureTestRenderViewHostFactory> render_view_host_factory_; 523 scoped_ptr<CaptureTestRenderViewHostFactory> render_view_host_factory_;
533 524
534 // A mocked-out browser and tab. 525 // A mocked-out browser and tab.
535 scoped_ptr<TestBrowserContext> browser_context_; 526 scoped_ptr<TestBrowserContext> browser_context_;
536 scoped_ptr<WebContents> web_contents_; 527 scoped_ptr<WebContents> web_contents_;
537 528
538 // Finally, the WebContentsVideoCaptureDevice under test. 529 // Finally, the WebContentsVideoCaptureDevice under test.
539 scoped_ptr<media::VideoCaptureDevice> device_; 530 scoped_ptr<media::VideoCaptureDevice> device_;
540 531
541 DISALLOW_COPY_AND_ASSIGN(WebContentsVideoCaptureDeviceTest); 532 TestBrowserThreadBundle thread_bundle_;
542 }; 533 };
543 534
544 TEST_F(WebContentsVideoCaptureDeviceTest, InvalidInitialWebContentsError) { 535 TEST_F(WebContentsVideoCaptureDeviceTest, InvalidInitialWebContentsError) {
545 // Before the installs itself on the UI thread up to start capturing, we'll 536 // Before the installs itself on the UI thread up to start capturing, we'll
546 // delete the web contents. This should trigger an error which can happen in 537 // delete the web contents. This should trigger an error which can happen in
547 // practice; we should be able to recover gracefully. 538 // practice; we should be able to recover gracefully.
548 ResetWebContents(); 539 ResetWebContents();
549 540
550 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer()); 541 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
551 device()->Start(); 542 device()->Start();
552 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForError()); 543 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForError());
553 device()->DeAllocate(); 544 device()->DeAllocate();
554 } 545 }
555 546
556 TEST_F(WebContentsVideoCaptureDeviceTest, WebContentsDestroyed) { 547 TEST_F(WebContentsVideoCaptureDeviceTest, WebContentsDestroyed) {
557 // We'll simulate the tab being closed after the capture pipeline is up and 548 // We'll simulate the tab being closed after the capture pipeline is up and
558 // running. 549 // running.
559 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer()); 550 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
560 device()->Start(); 551 device()->Start();
561 552
562 // Do one capture to prove 553 // Do one capture to prove
563 source()->SetSolidColor(SK_ColorRED); 554 source()->SetSolidColor(SK_ColorRED);
564 SimulateDrawEvent(); 555 SimulateDrawEvent();
565 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorRED)); 556 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorRED));
566 557
567 content::RunAllPendingInMessageLoop(); 558 base::RunLoop().RunUntilIdle();
568 559
569 // Post a task to close the tab. We should see an error reported to the 560 // Post a task to close the tab. We should see an error reported to the
570 // consumer. 561 // consumer.
571 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 562 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
572 base::Bind(&WebContentsVideoCaptureDeviceTest::ResetWebContents, 563 base::Bind(&WebContentsVideoCaptureDeviceTest::ResetWebContents,
573 base::Unretained(this))); 564 base::Unretained(this)));
574 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForError()); 565 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForError());
575 device()->DeAllocate(); 566 device()->DeAllocate();
576 } 567 }
577 568
578 TEST_F(WebContentsVideoCaptureDeviceTest, 569 TEST_F(WebContentsVideoCaptureDeviceTest,
579 StopDeviceBeforeCaptureMachineCreation) { 570 StopDeviceBeforeCaptureMachineCreation) {
580 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer()); 571 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
581 device()->Start(); 572 device()->Start();
582 // Make a point of not running the UI messageloop here. 573 // Make a point of not running the UI messageloop here.
583 device()->Stop(); 574 device()->Stop();
584 device()->DeAllocate(); 575 device()->DeAllocate();
585 DestroyVideoCaptureDevice(); 576 DestroyVideoCaptureDevice();
586 577
587 // Currently, there should be CreateCaptureMachineOnUIThread() and 578 // Currently, there should be CreateCaptureMachineOnUIThread() and
588 // DestroyCaptureMachineOnUIThread() tasks pending on the current (UI) message 579 // DestroyCaptureMachineOnUIThread() tasks pending on the current (UI) message
589 // loop. These should both succeed without crashing, and the machine should 580 // loop. These should both succeed without crashing, and the machine should
590 // wind up in the idle state. 581 // wind up in the idle state.
591 content::RunAllPendingInMessageLoop(); 582 base::RunLoop().RunUntilIdle();
592 } 583 }
593 584
594 TEST_F(WebContentsVideoCaptureDeviceTest, StopWithRendererWorkToDo) { 585 TEST_F(WebContentsVideoCaptureDeviceTest, StopWithRendererWorkToDo) {
595 // Set up the test to use RGB copies and an normal 586 // Set up the test to use RGB copies and an normal
596 source()->SetCanCopyToVideoFrame(false); 587 source()->SetCanCopyToVideoFrame(false);
597 source()->SetUseFrameSubscriber(false); 588 source()->SetUseFrameSubscriber(false);
598 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, 589 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond,
599 consumer()); 590 consumer());
600 device()->Start(); 591 device()->Start();
601 // Make a point of not running the UI messageloop here. 592 // Make a point of not running the UI messageloop here.
602 content::RunAllPendingInMessageLoop(); 593 // TODO(ajwong): Why do we care?
594 base::RunLoop().RunUntilIdle();
603 595
604 for (int i = 0; i < 10; ++i) 596 for (int i = 0; i < 10; ++i)
605 SimulateDrawEvent(); 597 SimulateDrawEvent();
606 598
607 device()->Stop(); 599 device()->Stop();
608 device()->DeAllocate(); 600 device()->DeAllocate();
609 // Currently, there should be CreateCaptureMachineOnUIThread() and 601 // Currently, there should be CreateCaptureMachineOnUIThread() and
610 // DestroyCaptureMachineOnUIThread() tasks pending on the current message 602 // DestroyCaptureMachineOnUIThread() tasks pending on the current message
611 // loop. These should both succeed without crashing, and the machine should 603 // loop. These should both succeed without crashing, and the machine should
612 // wind up in the idle state. 604 // wind up in the idle state.
613 ASSERT_FALSE(consumer()->HasError()); 605 ASSERT_FALSE(consumer()->HasError());
614 content::RunAllPendingInMessageLoop(); 606 base::RunLoop().RunUntilIdle();
615 ASSERT_FALSE(consumer()->HasError()); 607 ASSERT_FALSE(consumer()->HasError());
616 } 608 }
617 609
618 TEST_F(WebContentsVideoCaptureDeviceTest, DeviceRestart) { 610 TEST_F(WebContentsVideoCaptureDeviceTest, DeviceRestart) {
619 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer()); 611 device()->Allocate(kTestWidth, kTestHeight, kTestFramesPerSecond, consumer());
620 device()->Start(); 612 device()->Start();
621 content::RunAllPendingInMessageLoop(); 613 base::RunLoop().RunUntilIdle();
622 source()->SetSolidColor(SK_ColorRED); 614 source()->SetSolidColor(SK_ColorRED);
623 SimulateDrawEvent(); 615 SimulateDrawEvent();
624 SimulateDrawEvent(); 616 SimulateDrawEvent();
625 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorRED)); 617 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorRED));
626 SimulateDrawEvent(); 618 SimulateDrawEvent();
627 SimulateDrawEvent(); 619 SimulateDrawEvent();
628 source()->SetSolidColor(SK_ColorGREEN); 620 source()->SetSolidColor(SK_ColorGREEN);
629 SimulateDrawEvent(); 621 SimulateDrawEvent();
630 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorGREEN)); 622 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorGREEN));
631 device()->Stop(); 623 device()->Stop();
632 624
633 // Device is stopped, but content can still be animating. 625 // Device is stopped, but content can still be animating.
634 SimulateDrawEvent(); 626 SimulateDrawEvent();
635 SimulateDrawEvent(); 627 SimulateDrawEvent();
636 content::RunAllPendingInMessageLoop(); 628 base::RunLoop().RunUntilIdle();
637 629
638 device()->Start(); 630 device()->Start();
639 source()->SetSolidColor(SK_ColorBLUE); 631 source()->SetSolidColor(SK_ColorBLUE);
640 SimulateDrawEvent(); 632 SimulateDrawEvent();
641 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorBLUE)); 633 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorBLUE));
642 source()->SetSolidColor(SK_ColorYELLOW); 634 source()->SetSolidColor(SK_ColorYELLOW);
643 SimulateDrawEvent(); 635 SimulateDrawEvent();
644 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorYELLOW)); 636 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorYELLOW));
645 device()->DeAllocate(); 637 device()->DeAllocate();
646 } 638 }
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorGREEN)); 718 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorGREEN));
727 source()->SetSolidColor(SK_ColorRED); 719 source()->SetSolidColor(SK_ColorRED);
728 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorRED)); 720 ASSERT_NO_FATAL_FAILURE(consumer()->WaitForNextColor(SK_ColorRED));
729 721
730 device()->Stop(); 722 device()->Stop();
731 device()->DeAllocate(); 723 device()->DeAllocate();
732 } 724 }
733 725
734 } // namespace 726 } // namespace
735 } // namespace content 727 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/gpu/shader_disk_cache_unittest.cc ('k') | content/browser/storage_partition_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698