Chromium Code Reviews| Index: content/browser/renderer_host/media/video_capture_manager_unittest.cc |
| diff --git a/content/browser/renderer_host/media/video_capture_manager_unittest.cc b/content/browser/renderer_host/media/video_capture_manager_unittest.cc |
| index 82c3e71c179d0fe5973cc982696f2c325e9406c7..9ec3c4453e8dfd2d1593024934bbb3e077ff25d7 100644 |
| --- a/content/browser/renderer_host/media/video_capture_manager_unittest.cc |
| +++ b/content/browser/renderer_host/media/video_capture_manager_unittest.cc |
| @@ -8,11 +8,14 @@ |
| #include <stdint.h> |
| +#include <algorithm> |
| #include <memory> |
| #include <string> |
| +#include <vector> |
| #include "base/bind.h" |
| #include "base/macros.h" |
| +#include "base/memory/ptr_util.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/run_loop.h" |
| #include "content/browser/browser_thread_impl.h" |
| @@ -33,6 +36,91 @@ using ::testing::SaveArg; |
| namespace content { |
| +namespace { |
| + |
| +// Wraps FakeVideoCaptureDeviceFactory to allow mocking of the |
| +// VideoCaptureDevice MaybeSuspend() and Resume() methods. This is used to check |
| +// that devices are asked to suspend or resume at the correct times. |
| +class WrappedDeviceFactory : public media::FakeVideoCaptureDeviceFactory { |
| + public: |
| + class WrappedDevice : public media::VideoCaptureDevice { |
| + public: |
| + WrappedDevice(std::unique_ptr<media::VideoCaptureDevice> device, |
| + WrappedDeviceFactory* factory) |
| + : device_(std::move(device)), factory_(factory) { |
| + factory_->OnDeviceCreated(this); |
| + } |
| + |
| + ~WrappedDevice() final { |
| + factory_->OnDeviceDestroyed(this); |
| + } |
| + |
| + void AllocateAndStart(const media::VideoCaptureParams& params, |
| + std::unique_ptr<Client> client) final { |
| + device_->AllocateAndStart(params, std::move(client)); |
| + } |
| + |
| + void RequestRefreshFrame() final { |
| + device_->RequestRefreshFrame(); |
| + } |
| + |
| + void MaybeSuspend() final { |
| + factory_->WillSuspendDevice(); |
| + device_->MaybeSuspend(); |
| + } |
| + |
| + void Resume() final { |
| + factory_->WillResumeDevice(); |
| + device_->Resume(); |
| + } |
| + |
| + void StopAndDeAllocate() final { |
| + device_->StopAndDeAllocate(); |
| + } |
| + |
| + void GetPhotoCapabilities(GetPhotoCapabilitiesCallback callback) final { |
| + device_->GetPhotoCapabilities(std::move(callback)); |
| + } |
| + |
| + void TakePhoto(TakePhotoCallback callback) final { |
| + device_->TakePhoto(std::move(callback)); |
| + } |
| + |
| + private: |
| + const std::unique_ptr<media::VideoCaptureDevice> device_; |
| + WrappedDeviceFactory* const factory_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(WrappedDevice); |
| + }; |
| + |
| + WrappedDeviceFactory() : FakeVideoCaptureDeviceFactory() {} |
| + ~WrappedDeviceFactory() final {} |
| + |
| + std::unique_ptr<media::VideoCaptureDevice> CreateDevice( |
| + const media::VideoCaptureDeviceDescriptor& device_descriptor) final { |
| + return base::MakeUnique<WrappedDevice>( |
| + FakeVideoCaptureDeviceFactory::CreateDevice(device_descriptor), this); |
| + } |
| + |
| + MOCK_METHOD0(WillSuspendDevice, void()); |
| + MOCK_METHOD0(WillResumeDevice, void()); |
| + |
| + private: |
| + void OnDeviceCreated(WrappedDevice* device) { |
| + devices_.push_back(device); |
| + } |
| + |
| + void OnDeviceDestroyed(WrappedDevice* device) { |
| + const auto it = std::find(devices_.begin(), devices_.end(), device); |
| + CHECK(it != devices_.end()); |
| + devices_.erase(it); |
| + } |
| + |
| + std::vector<WrappedDevice*> devices_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(WrappedDeviceFactory); |
| +}; |
| + |
| // Listener class used to track progress of VideoCaptureManager test. |
| class MockMediaStreamProviderListener : public MediaStreamProviderListener { |
| public: |
| @@ -65,6 +153,8 @@ class MockFrameObserver : public VideoCaptureControllerEventHandler { |
| void OnGotControllerCallback(VideoCaptureControllerID) {} |
| }; |
| +} // namespace |
| + |
| // Test class |
| class VideoCaptureManagerTest : public testing::Test { |
| public: |
| @@ -93,10 +183,9 @@ class VideoCaptureManagerTest : public testing::Test { |
| message_loop_.get())); |
| vcm_ = new VideoCaptureManager( |
| std::unique_ptr<media::VideoCaptureDeviceFactory>( |
| - new media::FakeVideoCaptureDeviceFactory())); |
| - video_capture_device_factory_ = |
| - static_cast<media::FakeVideoCaptureDeviceFactory*>( |
| - vcm_->video_capture_device_factory()); |
| + new WrappedDeviceFactory())); |
| + video_capture_device_factory_ = static_cast<WrappedDeviceFactory*>( |
| + vcm_->video_capture_device_factory()); |
| const int32_t kNumberOfFakeDevices = 2; |
|
mcasas
2016/09/28 21:34:44
nit: totally unrelated to this CL, but it seems li
miu
2016/09/28 22:35:15
Agree! Let's encourage others to stop thinking lik
|
| video_capture_device_factory_->set_number_of_devices(kNumberOfFakeDevices); |
| vcm_->Register(listener_.get(), message_loop_->task_runner().get()); |
| @@ -114,7 +203,6 @@ class VideoCaptureManagerTest : public testing::Test { |
| void OnGotControllerCallback( |
| VideoCaptureControllerID id, |
| - base::Closure quit_closure, |
| bool expect_success, |
| const base::WeakPtr<VideoCaptureController>& controller) { |
| if (expect_success) { |
| @@ -124,7 +212,6 @@ class VideoCaptureManagerTest : public testing::Test { |
| } else { |
| ASSERT_FALSE(controller); |
| } |
| - quit_closure.Run(); |
| } |
| VideoCaptureControllerID StartClient(int session_id, bool expect_success) { |
| @@ -133,7 +220,6 @@ class VideoCaptureManagerTest : public testing::Test { |
| gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); |
| VideoCaptureControllerID client_id(next_client_id_++); |
| - base::RunLoop run_loop; |
| vcm_->StartCaptureForClient( |
| session_id, |
| params, |
| @@ -143,9 +229,8 @@ class VideoCaptureManagerTest : public testing::Test { |
| base::Bind(&VideoCaptureManagerTest::OnGotControllerCallback, |
| base::Unretained(this), |
| client_id, |
| - run_loop.QuitClosure(), |
| expect_success)); |
| - run_loop.Run(); |
| + base::RunLoop().RunUntilIdle(); |
| return client_id; |
| } |
| @@ -161,19 +246,22 @@ class VideoCaptureManagerTest : public testing::Test { |
| media::VideoCaptureParams params; |
| params.requested_format = media::VideoCaptureFormat( |
| gfx::Size(320, 240), 30, media::PIXEL_FORMAT_I420); |
| - |
| vcm_->ResumeCaptureForClient( |
| session_id, |
| params, |
| controllers_[client_id], |
| client_id, |
| frame_observer_.get()); |
| + // Allow possible VideoCaptureDevice::Resume() task to run. |
| + base::RunLoop().RunUntilIdle(); |
| } |
| void PauseClient(VideoCaptureControllerID client_id) { |
| ASSERT_EQ(1u, controllers_.count(client_id)); |
| vcm_->PauseCaptureForClient(controllers_[client_id], client_id, |
| - frame_observer_.get()); |
| + frame_observer_.get()); |
| + // Allow possible VideoCaptureDevice::MaybeSuspend() task to run. |
| + base::RunLoop().RunUntilIdle(); |
| } |
| #if defined(OS_ANDROID) |
| @@ -190,7 +278,7 @@ class VideoCaptureManagerTest : public testing::Test { |
| std::unique_ptr<BrowserThreadImpl> ui_thread_; |
| std::unique_ptr<BrowserThreadImpl> io_thread_; |
| std::unique_ptr<MockFrameObserver> frame_observer_; |
| - media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_; |
| + WrappedDeviceFactory* video_capture_device_factory_; |
| StreamDeviceInfoArray devices_; |
| private: |
| @@ -476,21 +564,38 @@ TEST_F(VideoCaptureManagerTest, CloseWithoutStop) { |
| vcm_->Unregister(); |
| } |
| -// Try to open, start, pause and resume a device. |
| +// Try to open, start, pause and resume a device. Confirm the device is |
| +// paused/resumed at the correct times in both single-client and multiple-client |
| +// scenarios. |
| TEST_F(VideoCaptureManagerTest, PauseAndResumeClient) { |
| - InSequence s; |
| EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)); |
| - EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)); |
| - int video_session_id = vcm_->Open(devices_.front()); |
| - VideoCaptureControllerID client_id = StartClient(video_session_id, true); |
| + const int video_session_id = vcm_->Open(devices_.front()); |
|
mcasas
2016/09/28 21:34:44
Yay!
|
| + const VideoCaptureControllerID client_id = |
| + StartClient(video_session_id, true); |
| - // Resume client a second time should cause no problem. |
| + // Test pause/resume when only one client is present. |
| + EXPECT_CALL(*video_capture_device_factory_, WillSuspendDevice()).Times(1); |
| PauseClient(client_id); |
| + EXPECT_CALL(*video_capture_device_factory_, WillResumeDevice()).Times(1); |
| ResumeClient(video_session_id, client_id); |
| + |
| + // Attempting to resume the client a second time should not cause any calls to |
| + // VideoCaptureDevice::Resume(). |
| + ResumeClient(video_session_id, client_id); |
| + |
| + // Add a second client that is never paused, then pause/resume the first |
| + // client, and no calls to VideoCaptureDevice::MaybeSuspend() or Resume() are |
| + // made. |
| + const VideoCaptureControllerID client_id2 = |
| + StartClient(video_session_id, true); |
| + PauseClient(client_id); |
| ResumeClient(video_session_id, client_id); |
| StopClient(client_id); |
| + StopClient(client_id2); |
| + |
| + EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)); |
| vcm_->Close(video_session_id); |
| // Wait to check callbacks before removing the listener. |