Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / renderer_host / media / video_capture_manager_unittest.cc
blob54b9c303ead128c46b3816f09eb320e7dd4bcb2a
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
3 // found in the LICENSE file.
5 // Unit test for VideoCaptureManager.
7 #include <string>
9 #include "base/bind.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h"
13 #include "base/process_util.h"
14 #include "content/browser/browser_thread_impl.h"
15 #include "content/browser/renderer_host/media/media_stream_provider.h"
16 #include "content/browser/renderer_host/media/video_capture_manager.h"
17 #include "content/common/media/media_stream_options.h"
18 #include "media/video/capture/video_capture_device.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
22 using ::testing::_;
23 using ::testing::AnyNumber;
24 using ::testing::InSequence;
25 using testing::SaveArg;
26 using ::testing::Return;
28 namespace content {
30 // Listener class used to track progress of VideoCaptureManager test.
31 class MockMediaStreamProviderListener : public MediaStreamProviderListener {
32 public:
33 MockMediaStreamProviderListener() {}
34 ~MockMediaStreamProviderListener() {}
36 MOCK_METHOD2(Opened, void(MediaStreamType, int));
37 MOCK_METHOD2(Closed, void(MediaStreamType, int));
38 MOCK_METHOD2(DevicesEnumerated, void(MediaStreamType,
39 const StreamDeviceInfoArray&));
40 MOCK_METHOD3(Error, void(MediaStreamType, int,
41 MediaStreamProviderError));
42 }; // class MockMediaStreamProviderListener
44 // Needed as an input argument to Start().
45 class MockFrameObserver : public media::VideoCaptureDevice::EventHandler {
46 public:
47 virtual scoped_refptr<media::VideoFrame> ReserveOutputBuffer() OVERRIDE {
48 return NULL;
50 virtual void OnError() OVERRIDE {}
51 virtual void OnFrameInfo(
52 const media::VideoCaptureCapability& info) OVERRIDE {}
53 virtual void OnIncomingCapturedFrame(const uint8* data,
54 int length,
55 base::Time timestamp,
56 int rotation,
57 bool flip_vert,
58 bool flip_horiz) OVERRIDE {}
59 virtual void OnIncomingCapturedVideoFrame(
60 const scoped_refptr<media::VideoFrame>& frame,
61 base::Time timestamp) OVERRIDE {}
64 // Test class
65 class VideoCaptureManagerTest : public testing::Test {
66 public:
67 VideoCaptureManagerTest() {}
68 virtual ~VideoCaptureManagerTest() {}
70 protected:
71 virtual void SetUp() OVERRIDE {
72 listener_.reset(new MockMediaStreamProviderListener());
73 message_loop_.reset(new base::MessageLoop(base::MessageLoop::TYPE_IO));
74 io_thread_.reset(new BrowserThreadImpl(BrowserThread::IO,
75 message_loop_.get()));
76 vcm_ = new VideoCaptureManager();
77 vcm_->UseFakeDevice();
78 vcm_->Register(listener_.get(), message_loop_->message_loop_proxy().get());
79 frame_observer_.reset(new MockFrameObserver());
82 virtual void TearDown() OVERRIDE {}
84 scoped_refptr<VideoCaptureManager> vcm_;
85 scoped_ptr<MockMediaStreamProviderListener> listener_;
86 scoped_ptr<base::MessageLoop> message_loop_;
87 scoped_ptr<BrowserThreadImpl> io_thread_;
88 scoped_ptr<MockFrameObserver> frame_observer_;
90 private:
91 DISALLOW_COPY_AND_ASSIGN(VideoCaptureManagerTest);
94 // Test cases
96 // Try to open, start, stop and close a device.
97 TEST_F(VideoCaptureManagerTest, CreateAndClose) {
98 StreamDeviceInfoArray devices;
100 InSequence s;
101 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
102 .Times(1).WillOnce(SaveArg<1>(&devices));
103 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
104 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
106 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
108 // Wait to get device callback.
109 message_loop_->RunUntilIdle();
111 int video_session_id = vcm_->Open(devices.front());
113 media::VideoCaptureParams capture_params;
114 capture_params.session_id = video_session_id;
115 capture_params.width = 320;
116 capture_params.height = 240;
117 capture_params.frame_per_second = 30;
118 vcm_->Start(capture_params, frame_observer_.get());
120 vcm_->Stop(video_session_id, base::Closure());
121 vcm_->Close(video_session_id);
123 // Wait to check callbacks before removing the listener.
124 message_loop_->RunUntilIdle();
125 vcm_->Unregister();
128 // Open the same device twice.
129 TEST_F(VideoCaptureManagerTest, OpenTwice) {
130 StreamDeviceInfoArray devices;
132 InSequence s;
133 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
134 .Times(1).WillOnce(SaveArg<1>(&devices));
135 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
136 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
138 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
140 // Wait to get device callback.
141 message_loop_->RunUntilIdle();
143 int video_session_id_first = vcm_->Open(devices.front());
145 // This should trigger an error callback with error code
146 // 'kDeviceAlreadyInUse'.
147 int video_session_id_second = vcm_->Open(devices.front());
148 EXPECT_NE(video_session_id_first, video_session_id_second);
150 vcm_->Close(video_session_id_first);
151 vcm_->Close(video_session_id_second);
153 // Wait to check callbacks before removing the listener.
154 message_loop_->RunUntilIdle();
155 vcm_->Unregister();
158 // Open two different devices.
159 TEST_F(VideoCaptureManagerTest, OpenTwo) {
160 StreamDeviceInfoArray devices;
162 InSequence s;
163 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
164 .Times(1).WillOnce(SaveArg<1>(&devices));
165 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
166 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(2);
168 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
170 // Wait to get device callback.
171 message_loop_->RunUntilIdle();
173 StreamDeviceInfoArray::iterator it = devices.begin();
175 int video_session_id_first = vcm_->Open(*it);
176 ++it;
177 int video_session_id_second = vcm_->Open(*it);
179 vcm_->Close(video_session_id_first);
180 vcm_->Close(video_session_id_second);
182 // Wait to check callbacks before removing the listener.
183 message_loop_->RunUntilIdle();
184 vcm_->Unregister();
187 // Try open a non-existing device.
188 TEST_F(VideoCaptureManagerTest, OpenNotExisting) {
189 StreamDeviceInfoArray devices;
191 InSequence s;
192 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
193 .Times(1).WillOnce(SaveArg<1>(&devices));
194 EXPECT_CALL(*listener_, Error(MEDIA_DEVICE_VIDEO_CAPTURE,
195 _, kDeviceNotAvailable))
196 .Times(1);
198 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
200 // Wait to get device callback.
201 message_loop_->RunUntilIdle();
203 MediaStreamType stream_type = MEDIA_DEVICE_VIDEO_CAPTURE;
204 std::string device_name("device_doesnt_exist");
205 std::string device_id("id_doesnt_exist");
206 StreamDeviceInfo dummy_device(stream_type, device_name, device_id, false);
208 // This should fail with error code 'kDeviceNotAvailable'.
209 vcm_->Open(dummy_device);
211 // Wait to check callbacks before removing the listener.
212 message_loop_->RunUntilIdle();
213 vcm_->Unregister();
216 // Start a device using "magic" id, i.e. call Start without calling Open.
217 TEST_F(VideoCaptureManagerTest, StartUsingId) {
218 InSequence s;
219 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
220 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
222 media::VideoCaptureParams capture_params;
223 capture_params.session_id = VideoCaptureManager::kStartOpenSessionId;
224 capture_params.width = 320;
225 capture_params.height = 240;
226 capture_params.frame_per_second = 30;
228 // Start shall trigger the Open callback.
229 vcm_->Start(capture_params, frame_observer_.get());
231 // Stop shall trigger the Close callback
232 vcm_->Stop(VideoCaptureManager::kStartOpenSessionId, base::Closure());
234 // Wait to check callbacks before removing the listener.
235 message_loop_->RunUntilIdle();
236 vcm_->Unregister();
239 // Open and start a device, close it before calling Stop.
240 TEST_F(VideoCaptureManagerTest, CloseWithoutStop) {
241 StreamDeviceInfoArray devices;
243 InSequence s;
244 EXPECT_CALL(*listener_, DevicesEnumerated(MEDIA_DEVICE_VIDEO_CAPTURE, _))
245 .Times(1).WillOnce(SaveArg<1>(&devices));
246 EXPECT_CALL(*listener_, Opened(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
247 EXPECT_CALL(*listener_, Closed(MEDIA_DEVICE_VIDEO_CAPTURE, _)).Times(1);
249 vcm_->EnumerateDevices(MEDIA_DEVICE_VIDEO_CAPTURE);
251 // Wait to get device callback.
252 message_loop_->RunUntilIdle();
254 int video_session_id = vcm_->Open(devices.front());
256 media::VideoCaptureParams capture_params;
257 capture_params.session_id = video_session_id;
258 capture_params.width = 320;
259 capture_params.height = 240;
260 capture_params.frame_per_second = 30;
261 vcm_->Start(capture_params, frame_observer_.get());
263 // Close will stop the running device, an assert will be triggered in
264 // VideoCaptureManager destructor otherwise.
265 vcm_->Close(video_session_id);
266 vcm_->Stop(video_session_id, base::Closure());
268 // Wait to check callbacks before removing the listener
269 message_loop_->RunUntilIdle();
270 vcm_->Unregister();
273 } // namespace content