Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / renderer / media / media_stream_dispatcher_unittest.cc
blob85fe8d8713f12b38634f9c2434eb1c449eb52691
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 #include <string>
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "content/common/media/media_stream_messages.h"
12 #include "content/public/common/media_stream_request.h"
13 #include "content/renderer/media/media_stream_dispatcher.h"
14 #include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
15 #include "media/audio/audio_parameters.h"
16 #include "testing/gtest/include/gtest/gtest.h"
17 #include "url/gurl.h"
19 namespace content {
20 namespace {
22 const int kRouteId = 0;
23 const int kAudioSessionId = 3;
24 const int kVideoSessionId = 5;
25 const int kRequestId1 = 10;
26 const int kRequestId2 = 20;
27 const int kRequestId3 = 30;
28 const int kRequestId4 = 40;
30 const MediaStreamType kAudioType = MEDIA_DEVICE_AUDIO_CAPTURE;
31 const MediaStreamType kVideoType = MEDIA_DEVICE_VIDEO_CAPTURE;
33 class MockMediaStreamDispatcherEventHandler
34 : public MediaStreamDispatcherEventHandler,
35 public base::SupportsWeakPtr<MockMediaStreamDispatcherEventHandler> {
36 public:
37 MockMediaStreamDispatcherEventHandler()
38 : request_id_(-1) {}
40 virtual void OnStreamGenerated(
41 int request_id,
42 const std::string &label,
43 const StreamDeviceInfoArray& audio_device_array,
44 const StreamDeviceInfoArray& video_device_array) OVERRIDE {
45 request_id_ = request_id;
46 label_ = label;
47 if (audio_device_array.size()) {
48 DCHECK(audio_device_array.size() == 1);
49 audio_device_ = audio_device_array[0];
51 if (video_device_array.size()) {
52 DCHECK(video_device_array.size() == 1);
53 video_device_ = video_device_array[0];
57 virtual void OnStreamGenerationFailed(
58 int request_id,
59 content::MediaStreamRequestResult result) OVERRIDE {
60 request_id_ = request_id;
63 virtual void OnDeviceStopped(const std::string& label,
64 const StreamDeviceInfo& device_info) OVERRIDE {
65 device_stopped_label_ = label;
66 if (IsVideoMediaType(device_info.device.type)) {
67 EXPECT_TRUE(StreamDeviceInfo::IsEqual(video_device_, device_info));
69 if (IsAudioInputMediaType(device_info.device.type)) {
70 EXPECT_TRUE(StreamDeviceInfo::IsEqual(audio_device_, device_info));
74 virtual void OnDevicesEnumerated(
75 int request_id,
76 const StreamDeviceInfoArray& device_array) OVERRIDE {
77 request_id_ = request_id;
80 virtual void OnDeviceOpened(
81 int request_id,
82 const std::string& label,
83 const StreamDeviceInfo& video_device) OVERRIDE {
84 request_id_ = request_id;
85 label_ = label;
88 virtual void OnDeviceOpenFailed(int request_id) OVERRIDE {
89 request_id_ = request_id;
92 void ResetStoredParameters() {
93 request_id_ = -1;
94 label_ = "";
95 device_stopped_label_ = "";
96 audio_device_ = StreamDeviceInfo();
97 video_device_ = StreamDeviceInfo();
100 int request_id_;
101 std::string label_;
102 std::string device_stopped_label_;
103 StreamDeviceInfo audio_device_;
104 StreamDeviceInfo video_device_;
107 class MediaStreamDispatcherUnderTest : public MediaStreamDispatcher {
108 public:
109 MediaStreamDispatcherUnderTest() : MediaStreamDispatcher(NULL) {}
111 using MediaStreamDispatcher::GetNextIpcIdForTest;
112 using RenderFrameObserver::OnMessageReceived;
115 class MediaStreamDispatcherTest : public ::testing::Test {
116 public:
117 MediaStreamDispatcherTest()
118 : dispatcher_(new MediaStreamDispatcherUnderTest()),
119 handler_(new MockMediaStreamDispatcherEventHandler),
120 security_origin_("http://test.com"),
121 request_id_(10) {
124 // Generates a request for a MediaStream and returns the request id that is
125 // used in IPC. Use this returned id in CompleteGenerateStream to identify
126 // the request.
127 int GenerateStream(const StreamOptions& options, int request_id) {
128 int next_ipc_id = dispatcher_->GetNextIpcIdForTest();
129 dispatcher_->GenerateStream(request_id, handler_.get()->AsWeakPtr(),
130 options, security_origin_);
131 return next_ipc_id;
134 // CompleteGenerateStream create a MediaStreamMsg_StreamGenerated instance
135 // and call the MediaStreamDispathcer::OnMessageReceived. |ipc_id| must be the
136 // the id returned by GenerateStream.
137 std::string CompleteGenerateStream(int ipc_id, const StreamOptions& options,
138 int request_id) {
139 StreamDeviceInfoArray audio_device_array(options.audio_requested ? 1 : 0);
140 if (options.audio_requested) {
141 StreamDeviceInfo audio_device_info;
142 audio_device_info.device.name = "Microphone";
143 audio_device_info.device.type = kAudioType;
144 audio_device_info.session_id = kAudioSessionId;
145 audio_device_array[0] = audio_device_info;
148 StreamDeviceInfoArray video_device_array(options.video_requested ? 1 : 0);
149 if (options.video_requested) {
150 StreamDeviceInfo video_device_info;
151 video_device_info.device.name = "Camera";
152 video_device_info.device.type = kVideoType;
153 video_device_info.session_id = kVideoSessionId;
154 video_device_array[0] = video_device_info;
157 std::string label = "stream" + base::IntToString(ipc_id);
159 handler_->ResetStoredParameters();
160 dispatcher_->OnMessageReceived(MediaStreamMsg_StreamGenerated(
161 kRouteId, ipc_id, label,
162 audio_device_array, video_device_array));
164 EXPECT_EQ(handler_->request_id_, request_id);
165 EXPECT_EQ(handler_->label_, label);
167 if (options.audio_requested)
168 EXPECT_EQ(dispatcher_->audio_session_id(label, 0), kAudioSessionId);
170 if (options.video_requested)
171 EXPECT_EQ(dispatcher_->video_session_id(label, 0), kVideoSessionId);
173 return label;
176 protected:
177 base::MessageLoop message_loop_;
178 scoped_ptr<MediaStreamDispatcherUnderTest> dispatcher_;
179 scoped_ptr<MockMediaStreamDispatcherEventHandler> handler_;
180 GURL security_origin_;
181 int request_id_;
184 } // namespace
186 TEST_F(MediaStreamDispatcherTest, GenerateStreamAndStopDevices) {
187 StreamOptions options(true, true);
189 int ipc_request_id1 = GenerateStream(options, kRequestId1);
190 int ipc_request_id2 = GenerateStream(options, kRequestId2);
191 EXPECT_NE(ipc_request_id1, ipc_request_id2);
193 // Complete the creation of stream1.
194 const std::string& label1 = CompleteGenerateStream(ipc_request_id1, options,
195 kRequestId1);
197 // Complete the creation of stream2.
198 const std::string& label2 = CompleteGenerateStream(ipc_request_id2, options,
199 kRequestId2);
201 // Stop the actual audio device and verify that there is no valid
202 // |session_id|.
203 dispatcher_->StopStreamDevice(handler_->audio_device_);
204 EXPECT_EQ(dispatcher_->audio_session_id(label1, 0),
205 StreamDeviceInfo::kNoId);
206 EXPECT_EQ(dispatcher_->audio_session_id(label2, 0),
207 StreamDeviceInfo::kNoId);
209 // Stop the actual video device and verify that there is no valid
210 // |session_id|.
211 dispatcher_->StopStreamDevice(handler_->video_device_);
212 EXPECT_EQ(dispatcher_->video_session_id(label1, 0),
213 StreamDeviceInfo::kNoId);
214 EXPECT_EQ(dispatcher_->video_session_id(label2, 0),
215 StreamDeviceInfo::kNoId);
218 TEST_F(MediaStreamDispatcherTest, BasicVideoDevice) {
219 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
220 scoped_ptr<MockMediaStreamDispatcherEventHandler>
221 handler1(new MockMediaStreamDispatcherEventHandler);
222 scoped_ptr<MockMediaStreamDispatcherEventHandler>
223 handler2(new MockMediaStreamDispatcherEventHandler);
224 GURL security_origin;
226 int ipc_request_id1 = dispatcher->next_ipc_id_;
227 dispatcher->EnumerateDevices(
228 kRequestId1, handler1.get()->AsWeakPtr(),
229 kVideoType,
230 security_origin);
231 int ipc_request_id2 = dispatcher->next_ipc_id_;
232 EXPECT_NE(ipc_request_id1, ipc_request_id2);
233 dispatcher->EnumerateDevices(
234 kRequestId2, handler2.get()->AsWeakPtr(),
235 kVideoType,
236 security_origin);
237 EXPECT_EQ(dispatcher->requests_.size(), size_t(2));
239 StreamDeviceInfoArray video_device_array(1);
240 StreamDeviceInfo video_device_info;
241 video_device_info.device.name = "Camera";
242 video_device_info.device.id = "device_path";
243 video_device_info.device.type = kVideoType;
244 video_device_info.session_id = kVideoSessionId;
245 video_device_array[0] = video_device_info;
247 // Complete the first enumeration request.
248 dispatcher->OnMessageReceived(MediaStreamMsg_DevicesEnumerated(
249 kRouteId, ipc_request_id1, video_device_array));
250 EXPECT_EQ(handler1->request_id_, kRequestId1);
252 dispatcher->OnMessageReceived(MediaStreamMsg_DevicesEnumerated(
253 kRouteId, ipc_request_id2, video_device_array));
254 EXPECT_EQ(handler2->request_id_, kRequestId2);
256 EXPECT_EQ(dispatcher->requests_.size(), size_t(2));
257 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0));
259 int ipc_request_id3 = dispatcher->next_ipc_id_;
260 dispatcher->OpenDevice(kRequestId3, handler1.get()->AsWeakPtr(),
261 video_device_info.device.id,
262 kVideoType,
263 security_origin);
264 int ipc_request_id4 = dispatcher->next_ipc_id_;
265 EXPECT_NE(ipc_request_id3, ipc_request_id4);
266 dispatcher->OpenDevice(kRequestId4, handler1.get()->AsWeakPtr(),
267 video_device_info.device.id,
268 kVideoType,
269 security_origin);
270 EXPECT_EQ(dispatcher->requests_.size(), size_t(4));
272 // Complete the OpenDevice of request 1.
273 std::string stream_label1 = std::string("stream1");
274 dispatcher->OnMessageReceived(MediaStreamMsg_DeviceOpened(
275 kRouteId, ipc_request_id3, stream_label1, video_device_info));
276 EXPECT_EQ(handler1->request_id_, kRequestId3);
278 // Complete the OpenDevice of request 2.
279 std::string stream_label2 = std::string("stream2");
280 dispatcher->OnMessageReceived(MediaStreamMsg_DeviceOpened(
281 kRouteId, ipc_request_id4, stream_label2, video_device_info));
282 EXPECT_EQ(handler1->request_id_, kRequestId4);
284 EXPECT_EQ(dispatcher->requests_.size(), size_t(2));
285 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(2));
287 // Check the video_session_id.
288 EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), kVideoSessionId);
289 EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0), kVideoSessionId);
291 // Close the device from request 2.
292 dispatcher->CloseDevice(stream_label2);
293 EXPECT_EQ(dispatcher->video_session_id(stream_label2, 0),
294 StreamDeviceInfo::kNoId);
296 // Close the device from request 1.
297 dispatcher->CloseDevice(stream_label1);
298 EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0),
299 StreamDeviceInfo::kNoId);
300 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0));
302 // Verify that the request have been completed.
303 EXPECT_EQ(dispatcher->label_stream_map_.size(), size_t(0));
304 EXPECT_EQ(dispatcher->requests_.size(), size_t(2));
307 TEST_F(MediaStreamDispatcherTest, TestFailure) {
308 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
309 scoped_ptr<MockMediaStreamDispatcherEventHandler>
310 handler(new MockMediaStreamDispatcherEventHandler);
311 StreamOptions components(true, true);
312 GURL security_origin;
314 // Test failure when creating a stream.
315 int ipc_request_id1 = dispatcher->next_ipc_id_;
316 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(),
317 components, security_origin);
318 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerationFailed(
319 kRouteId, ipc_request_id1, MEDIA_DEVICE_PERMISSION_DENIED));
321 // Verify that the request have been completed.
322 EXPECT_EQ(handler->request_id_, kRequestId1);
323 EXPECT_EQ(dispatcher->requests_.size(), size_t(0));
325 // Create a new stream.
326 ipc_request_id1 = dispatcher->next_ipc_id_;
327 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(),
328 components, security_origin);
330 StreamDeviceInfoArray audio_device_array(1);
331 StreamDeviceInfo audio_device_info;
332 audio_device_info.device.name = "Microphone";
333 audio_device_info.device.type = kAudioType;
334 audio_device_info.session_id = kAudioSessionId;
335 audio_device_array[0] = audio_device_info;
337 StreamDeviceInfoArray video_device_array(1);
338 StreamDeviceInfo video_device_info;
339 video_device_info.device.name = "Camera";
340 video_device_info.device.type = kVideoType;
341 video_device_info.session_id = kVideoSessionId;
342 video_device_array[0] = video_device_info;
344 // Complete the creation of stream1.
345 std::string stream_label1 = std::string("stream1");
346 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated(
347 kRouteId, ipc_request_id1, stream_label1,
348 audio_device_array, video_device_array));
349 EXPECT_EQ(handler->request_id_, kRequestId1);
350 EXPECT_EQ(handler->label_, stream_label1);
351 EXPECT_EQ(dispatcher->video_session_id(stream_label1, 0), kVideoSessionId);
354 TEST_F(MediaStreamDispatcherTest, CancelGenerateStream) {
355 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
356 scoped_ptr<MockMediaStreamDispatcherEventHandler>
357 handler(new MockMediaStreamDispatcherEventHandler);
358 StreamOptions components(true, true);
359 int ipc_request_id1 = dispatcher->next_ipc_id_;
361 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(),
362 components, GURL());
363 dispatcher->GenerateStream(kRequestId2, handler.get()->AsWeakPtr(),
364 components, GURL());
366 EXPECT_EQ(2u, dispatcher->requests_.size());
367 dispatcher->CancelGenerateStream(kRequestId2, handler.get()->AsWeakPtr());
368 EXPECT_EQ(1u, dispatcher->requests_.size());
370 // Complete the creation of stream1.
371 StreamDeviceInfo audio_device_info;
372 audio_device_info.device.name = "Microphone";
373 audio_device_info.device.type = kAudioType;
374 audio_device_info.session_id = kAudioSessionId;
375 StreamDeviceInfoArray audio_device_array(1);
376 audio_device_array[0] = audio_device_info;
378 StreamDeviceInfo video_device_info;
379 video_device_info.device.name = "Camera";
380 video_device_info.device.type = kVideoType;
381 video_device_info.session_id = kVideoSessionId;
382 StreamDeviceInfoArray video_device_array(1);
383 video_device_array[0] = video_device_info;
385 std::string stream_label1 = "stream1";
386 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated(
387 kRouteId, ipc_request_id1, stream_label1,
388 audio_device_array, video_device_array));
389 EXPECT_EQ(handler->request_id_, kRequestId1);
390 EXPECT_EQ(handler->label_, stream_label1);
391 EXPECT_EQ(0u, dispatcher->requests_.size());
394 // Test that the MediaStreamDispatcherEventHandler is notified when the message
395 // MediaStreamMsg_DeviceStopped is received.
396 TEST_F(MediaStreamDispatcherTest, DeviceClosed) {
397 StreamOptions options(true, true);
399 int ipc_request_id = GenerateStream(options, kRequestId1);
400 const std::string& label = CompleteGenerateStream(ipc_request_id, options,
401 kRequestId1);
403 dispatcher_->OnMessageReceived(
404 MediaStreamMsg_DeviceStopped(kRouteId, label, handler_->video_device_));
405 // Verify that MediaStreamDispatcherEventHandler::OnDeviceStopped has been
406 // called.
407 EXPECT_EQ(label, handler_->device_stopped_label_);
408 EXPECT_EQ(dispatcher_->video_session_id(label, 0),
409 StreamDeviceInfo::kNoId);
412 TEST_F(MediaStreamDispatcherTest, CheckDuckingState) {
413 scoped_ptr<MediaStreamDispatcher> dispatcher(new MediaStreamDispatcher(NULL));
414 scoped_ptr<MockMediaStreamDispatcherEventHandler>
415 handler(new MockMediaStreamDispatcherEventHandler);
416 StreamOptions components(true, false); // audio only.
417 int ipc_request_id1 = dispatcher->next_ipc_id_;
419 dispatcher->GenerateStream(kRequestId1, handler.get()->AsWeakPtr(),
420 components, GURL());
421 EXPECT_EQ(1u, dispatcher->requests_.size());
423 // Ducking isn't active at this point.
424 EXPECT_FALSE(dispatcher->IsAudioDuckingActive());
426 // Complete the creation of stream1 with a single audio track that has
427 // ducking enabled.
428 StreamDeviceInfoArray audio_device_array(1);
429 StreamDeviceInfo& audio_device_info = audio_device_array[0];
430 audio_device_info.device.name = "Microphone";
431 audio_device_info.device.type = kAudioType;
432 audio_device_info.session_id = kAudioSessionId;
433 audio_device_info.device.input.effects = media::AudioParameters::DUCKING;
435 StreamDeviceInfoArray video_device_array; // Empty for this test.
437 const char kStreamLabel[] = "stream1";
438 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated(
439 kRouteId, ipc_request_id1, kStreamLabel,
440 audio_device_array, video_device_array));
441 EXPECT_EQ(handler->request_id_, kRequestId1);
442 EXPECT_EQ(0u, dispatcher->requests_.size());
444 // Ducking should now be reported as active.
445 EXPECT_TRUE(dispatcher->IsAudioDuckingActive());
447 // Stop the device (removes the stream).
448 dispatcher->OnMessageReceived(
449 MediaStreamMsg_DeviceStopped(kRouteId, kStreamLabel,
450 handler->audio_device_));
452 // Ducking should now be reported as inactive again.
453 EXPECT_FALSE(dispatcher->IsAudioDuckingActive());
455 // Now do the same sort of test with the DUCKING flag off.
456 audio_device_info.device.input.effects =
457 media::AudioParameters::ECHO_CANCELLER;
459 dispatcher->OnMessageReceived(MediaStreamMsg_StreamGenerated(
460 kRouteId, ipc_request_id1, kStreamLabel,
461 audio_device_array, video_device_array));
462 EXPECT_EQ(handler->request_id_, kRequestId1);
463 EXPECT_EQ(0u, dispatcher->requests_.size());
465 // Ducking should still be reported as not active.
466 EXPECT_FALSE(dispatcher->IsAudioDuckingActive());
468 // Stop the device (removes the stream).
469 dispatcher->OnMessageReceived(
470 MediaStreamMsg_DeviceStopped(kRouteId, kStreamLabel,
471 handler->audio_device_));
474 } // namespace content