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.
7 #include "base/memory/ref_counted.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop.h"
10 #include "content/common/media/media_stream_messages.h"
11 #include "content/public/common/media_stream_request.h"
12 #include "content/renderer/media/media_stream_dispatcher.h"
13 #include "content/renderer/media/media_stream_dispatcher_eventhandler.h"
14 #include "googleurl/src/gurl.h"
15 #include "testing/gtest/include/gtest/gtest.h"
20 const int kRouteId
= 0;
21 const int kAudioSessionId
= 3;
22 const int kVideoSessionId
= 5;
23 const int kRequestId1
= 10;
24 const int kRequestId2
= 20;
25 const int kRequestId3
= 30;
26 const int kRequestId4
= 40;
27 static const char kLabel
[] = "test";
29 const MediaStreamType kAudioType
= MEDIA_DEVICE_AUDIO_CAPTURE
;
30 const MediaStreamType kVideoType
= MEDIA_DEVICE_VIDEO_CAPTURE
;
31 const MediaStreamType kNoAudioType
= MEDIA_NO_SERVICE
;
33 class MockMediaStreamDispatcherEventHandler
34 : public MediaStreamDispatcherEventHandler
,
35 public base::SupportsWeakPtr
<MockMediaStreamDispatcherEventHandler
> {
37 MockMediaStreamDispatcherEventHandler()
40 virtual void OnStreamGenerated(
42 const std::string
&label
,
43 const StreamDeviceInfoArray
& audio_device_array
,
44 const StreamDeviceInfoArray
& video_device_array
) OVERRIDE
{
45 request_id_
= request_id
;
49 virtual void OnStreamGenerationFailed(int request_id
) OVERRIDE
{
50 request_id_
= request_id
;
53 virtual void OnDevicesEnumerated(
55 const StreamDeviceInfoArray
& device_array
) OVERRIDE
{
56 request_id_
= request_id
;
59 virtual void OnDevicesEnumerationFailed(int request_id
) OVERRIDE
{
60 request_id_
= request_id
;
63 virtual void OnDeviceOpened(
65 const std::string
& label
,
66 const StreamDeviceInfo
& video_device
) OVERRIDE
{
67 request_id_
= request_id
;
71 virtual void OnDeviceOpenFailed(int request_id
) OVERRIDE
{
72 request_id_
= request_id
;
78 DISALLOW_COPY_AND_ASSIGN(MockMediaStreamDispatcherEventHandler
);
83 TEST(MediaStreamDispatcherTest
, BasicStream
) {
84 scoped_ptr
<MessageLoop
> message_loop(new MessageLoop());
85 scoped_ptr
<MediaStreamDispatcher
> dispatcher(new MediaStreamDispatcher(NULL
));
86 scoped_ptr
<MockMediaStreamDispatcherEventHandler
>
87 handler(new MockMediaStreamDispatcherEventHandler
);
88 StreamOptions
components(kAudioType
, kVideoType
);
91 int ipc_request_id1
= dispatcher
->next_ipc_id_
;
92 dispatcher
->GenerateStream(kRequestId1
, handler
.get()->AsWeakPtr(),
93 components
, security_origin
);
94 int ipc_request_id2
= dispatcher
->next_ipc_id_
;
95 EXPECT_NE(ipc_request_id1
, ipc_request_id2
);
96 dispatcher
->GenerateStream(kRequestId2
, handler
.get()->AsWeakPtr(),
97 components
, security_origin
);
98 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(2));
100 StreamDeviceInfoArray
audio_device_array(1);
101 StreamDeviceInfo audio_device_info
;
102 audio_device_info
.device
.name
= "Microphone";
103 audio_device_info
.device
.type
= kAudioType
;
104 audio_device_info
.session_id
= kAudioSessionId
;
105 audio_device_array
[0] = audio_device_info
;
107 StreamDeviceInfoArray
video_device_array(1);
108 StreamDeviceInfo video_device_info
;
109 video_device_info
.device
.name
= "Camera";
110 video_device_info
.device
.type
= kVideoType
;
111 video_device_info
.session_id
= kVideoSessionId
;
112 video_device_array
[0] = video_device_info
;
114 // Complete the creation of stream1.
115 std::string stream_label1
= std::string("stream1");
116 dispatcher
->OnMessageReceived(MediaStreamMsg_StreamGenerated(
117 kRouteId
, ipc_request_id1
, stream_label1
,
118 audio_device_array
, video_device_array
));
119 EXPECT_EQ(handler
->request_id_
, kRequestId1
);
120 EXPECT_EQ(handler
->label_
, stream_label1
);
122 // Complete the creation of stream2.
123 std::string stream_label2
= std::string("stream2");
124 dispatcher
->OnMessageReceived(MediaStreamMsg_StreamGenerated(
125 kRouteId
, ipc_request_id2
, stream_label2
,
126 audio_device_array
, video_device_array
));
127 EXPECT_EQ(handler
->request_id_
, kRequestId2
);
128 EXPECT_EQ(handler
->label_
, stream_label2
);
130 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(0));
131 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(2));
133 // Check the session_id of stream2.
134 EXPECT_EQ(dispatcher
->audio_session_id(stream_label2
, 0), kAudioSessionId
);
135 EXPECT_EQ(dispatcher
->video_session_id(stream_label2
, 0), kVideoSessionId
);
138 dispatcher
->StopStream(stream_label2
);
139 EXPECT_EQ(dispatcher
->audio_session_id(stream_label2
, 0),
140 StreamDeviceInfo::kNoId
);
141 EXPECT_EQ(dispatcher
->video_session_id(stream_label2
, 0),
142 StreamDeviceInfo::kNoId
);
145 dispatcher
->StopStream(stream_label1
);
146 EXPECT_EQ(dispatcher
->audio_session_id(stream_label1
, 0),
147 StreamDeviceInfo::kNoId
);
148 EXPECT_EQ(dispatcher
->video_session_id(stream_label1
, 0),
149 StreamDeviceInfo::kNoId
);
150 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(0));
152 // Verify that the request has been completed.
153 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(0));
154 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(0));
157 TEST(MediaStreamDispatcherTest
, BasicStreamForDevice
) {
158 static const char kDeviceId
[] = "/dev/video0";
160 scoped_ptr
<MessageLoop
> message_loop(new MessageLoop());
161 scoped_ptr
<MediaStreamDispatcher
> dispatcher(new MediaStreamDispatcher(NULL
));
162 scoped_ptr
<MockMediaStreamDispatcherEventHandler
>
163 handler(new MockMediaStreamDispatcherEventHandler
);
164 StreamOptions
components(kNoAudioType
, kVideoType
);
165 components
.audio_device_id
= kDeviceId
;
166 components
.video_device_id
= kDeviceId
;
167 GURL security_origin
;
169 int ipc_request_id1
= dispatcher
->next_ipc_id_
;
170 dispatcher
->GenerateStream(kRequestId1
, handler
.get()->AsWeakPtr(),
171 components
, security_origin
);
172 int ipc_request_id2
= dispatcher
->next_ipc_id_
;
173 EXPECT_NE(ipc_request_id1
, ipc_request_id2
);
174 dispatcher
->GenerateStream(kRequestId2
, handler
.get()->AsWeakPtr(),
175 components
, security_origin
);
176 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(2));
178 // No audio requested.
179 StreamDeviceInfoArray audio_device_array
;
181 StreamDeviceInfoArray
video_device_array(1);
182 StreamDeviceInfo video_device_info
;
183 video_device_info
.device
.name
= "Fake Video Capture Device";
184 video_device_info
.device
.type
= kVideoType
;
185 video_device_info
.session_id
= kVideoSessionId
;
186 video_device_array
[0] = video_device_info
;
188 // Complete the creation of stream1.
189 std::string stream_label1
= std::string("stream1");
190 dispatcher
->OnMessageReceived(MediaStreamMsg_StreamGenerated(
191 kRouteId
, ipc_request_id1
, stream_label1
,
192 audio_device_array
, video_device_array
));
193 EXPECT_EQ(handler
->request_id_
, kRequestId1
);
194 EXPECT_EQ(handler
->label_
, stream_label1
);
196 // Complete the creation of stream2.
197 std::string stream_label2
= std::string("stream2");
198 dispatcher
->OnMessageReceived(MediaStreamMsg_StreamGenerated(
199 kRouteId
, ipc_request_id2
, stream_label2
,
200 audio_device_array
, video_device_array
));
201 EXPECT_EQ(handler
->request_id_
, kRequestId2
);
202 EXPECT_EQ(handler
->label_
, stream_label2
);
204 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(0));
205 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(2));
207 // Check the session_id of stream2.
208 EXPECT_EQ(dispatcher
->video_session_id(stream_label2
, 0), kVideoSessionId
);
211 dispatcher
->StopStream(stream_label2
);
212 EXPECT_EQ(dispatcher
->audio_session_id(stream_label2
, 0),
213 StreamDeviceInfo::kNoId
);
214 EXPECT_EQ(dispatcher
->video_session_id(stream_label2
, 0),
215 StreamDeviceInfo::kNoId
);
218 dispatcher
->StopStream(stream_label1
);
219 EXPECT_EQ(dispatcher
->audio_session_id(stream_label1
, 0),
220 StreamDeviceInfo::kNoId
);
221 EXPECT_EQ(dispatcher
->video_session_id(stream_label1
, 0),
222 StreamDeviceInfo::kNoId
);
223 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(0));
225 // Verify that the request has been completed.
226 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(0));
227 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(0));
230 TEST(MediaStreamDispatcherTest
, BasicVideoDevice
) {
231 scoped_ptr
<MessageLoop
> message_loop(new MessageLoop());
232 scoped_ptr
<MediaStreamDispatcher
> dispatcher(new MediaStreamDispatcher(NULL
));
233 scoped_ptr
<MockMediaStreamDispatcherEventHandler
>
234 handler1(new MockMediaStreamDispatcherEventHandler
);
235 scoped_ptr
<MockMediaStreamDispatcherEventHandler
>
236 handler2(new MockMediaStreamDispatcherEventHandler
);
237 GURL security_origin
;
239 int ipc_request_id1
= dispatcher
->next_ipc_id_
;
240 dispatcher
->EnumerateDevices(
241 kRequestId1
, handler1
.get()->AsWeakPtr(),
244 int ipc_request_id2
= dispatcher
->next_ipc_id_
;
245 EXPECT_NE(ipc_request_id1
, ipc_request_id2
);
246 dispatcher
->EnumerateDevices(
247 kRequestId2
, handler2
.get()->AsWeakPtr(),
250 EXPECT_EQ(dispatcher
->video_enumeration_state_
.requests
.size(), size_t(2));
252 StreamDeviceInfoArray
video_device_array(1);
253 StreamDeviceInfo video_device_info
;
254 video_device_info
.device
.name
= "Camera";
255 video_device_info
.device
.id
= "device_path";
256 video_device_info
.device
.type
= kVideoType
;
257 video_device_info
.session_id
= kVideoSessionId
;
258 video_device_array
[0] = video_device_info
;
260 // Complete the enumeration request and all requesters should receive reply.
261 dispatcher
->OnMessageReceived(MediaStreamMsg_DevicesEnumerated(
262 kRouteId
, ipc_request_id1
, kLabel
, video_device_array
));
263 EXPECT_EQ(handler1
->request_id_
, kRequestId1
);
264 EXPECT_EQ(handler2
->request_id_
, kRequestId2
);
266 EXPECT_EQ(dispatcher
->video_enumeration_state_
.requests
.size(), size_t(2));
267 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(0));
269 int ipc_request_id3
= dispatcher
->next_ipc_id_
;
270 dispatcher
->OpenDevice(kRequestId3
, handler1
.get()->AsWeakPtr(),
271 video_device_info
.device
.id
,
274 int ipc_request_id4
= dispatcher
->next_ipc_id_
;
275 EXPECT_NE(ipc_request_id3
, ipc_request_id4
);
276 dispatcher
->OpenDevice(kRequestId4
, handler1
.get()->AsWeakPtr(),
277 video_device_info
.device
.id
,
280 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(2));
282 // Complete the OpenDevice of request 1.
283 std::string stream_label1
= std::string("stream1");
284 dispatcher
->OnMessageReceived(MediaStreamMsg_DeviceOpened(
285 kRouteId
, ipc_request_id3
, stream_label1
, video_device_info
));
286 EXPECT_EQ(handler1
->request_id_
, kRequestId3
);
288 // Complete the OpenDevice of request 2.
289 std::string stream_label2
= std::string("stream2");
290 dispatcher
->OnMessageReceived(MediaStreamMsg_DeviceOpened(
291 kRouteId
, ipc_request_id4
, stream_label2
, video_device_info
));
292 EXPECT_EQ(handler1
->request_id_
, kRequestId4
);
294 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(0));
295 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(2));
297 // Check the video_session_id.
298 EXPECT_EQ(dispatcher
->video_session_id(stream_label1
, 0), kVideoSessionId
);
299 EXPECT_EQ(dispatcher
->video_session_id(stream_label2
, 0), kVideoSessionId
);
302 dispatcher
->StopStream(stream_label2
);
303 EXPECT_EQ(dispatcher
->video_session_id(stream_label2
, 0),
304 StreamDeviceInfo::kNoId
);
307 dispatcher
->StopStream(stream_label1
);
308 EXPECT_EQ(dispatcher
->video_session_id(stream_label1
, 0),
309 StreamDeviceInfo::kNoId
);
310 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(0));
312 // Verify that the request have been completed.
313 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(0));
314 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(0));
317 TEST(MediaStreamDispatcherTest
, TestFailure
) {
318 scoped_ptr
<MessageLoop
> message_loop(new MessageLoop());
319 scoped_ptr
<MediaStreamDispatcher
> dispatcher(new MediaStreamDispatcher(NULL
));
320 scoped_ptr
<MockMediaStreamDispatcherEventHandler
>
321 handler(new MockMediaStreamDispatcherEventHandler
);
322 StreamOptions
components(kAudioType
, kVideoType
);
323 GURL security_origin
;
325 // Test failure when creating a stream.
326 int ipc_request_id1
= dispatcher
->next_ipc_id_
;
327 dispatcher
->GenerateStream(kRequestId1
, handler
.get()->AsWeakPtr(),
328 components
, security_origin
);
329 dispatcher
->OnMessageReceived(MediaStreamMsg_StreamGenerationFailed(
330 kRouteId
, ipc_request_id1
));
332 // Verify that the request have been completed.
333 EXPECT_EQ(handler
->request_id_
, kRequestId1
);
334 EXPECT_EQ(dispatcher
->requests_
.size(), size_t(0));
336 // Create a new stream.
337 ipc_request_id1
= dispatcher
->next_ipc_id_
;
338 dispatcher
->GenerateStream(kRequestId1
, handler
.get()->AsWeakPtr(),
339 components
, security_origin
);
341 StreamDeviceInfoArray
audio_device_array(1);
342 StreamDeviceInfo audio_device_info
;
343 audio_device_info
.device
.name
= "Microphone";
344 audio_device_info
.device
.type
= kAudioType
;
345 audio_device_info
.session_id
= kAudioSessionId
;
346 audio_device_array
[0] = audio_device_info
;
348 StreamDeviceInfoArray
video_device_array(1);
349 StreamDeviceInfo video_device_info
;
350 video_device_info
.device
.name
= "Camera";
351 video_device_info
.device
.type
= kVideoType
;
352 video_device_info
.session_id
= kVideoSessionId
;
353 video_device_array
[0] = video_device_info
;
355 // Complete the creation of stream1.
356 std::string stream_label1
= std::string("stream1");
357 dispatcher
->OnMessageReceived(MediaStreamMsg_StreamGenerated(
358 kRouteId
, ipc_request_id1
, stream_label1
,
359 audio_device_array
, video_device_array
));
360 EXPECT_EQ(handler
->request_id_
, kRequestId1
);
361 EXPECT_EQ(handler
->label_
, stream_label1
);
362 EXPECT_EQ(dispatcher
->video_session_id(stream_label1
, 0), kVideoSessionId
);
365 dispatcher
->StopStream(stream_label1
);
366 EXPECT_EQ(dispatcher
->label_stream_map_
.size(), size_t(0));
369 TEST(MediaStreamDispatcherTest
, CancelGenerateStream
) {
370 scoped_ptr
<MessageLoop
> message_loop(new MessageLoop());
371 scoped_ptr
<MediaStreamDispatcher
> dispatcher(new MediaStreamDispatcher(NULL
));
372 scoped_ptr
<MockMediaStreamDispatcherEventHandler
>
373 handler(new MockMediaStreamDispatcherEventHandler
);
374 StreamOptions
components(kAudioType
, kVideoType
);
375 int ipc_request_id1
= dispatcher
->next_ipc_id_
;
377 dispatcher
->GenerateStream(kRequestId1
, handler
.get()->AsWeakPtr(),
379 dispatcher
->GenerateStream(kRequestId2
, handler
.get()->AsWeakPtr(),
382 EXPECT_EQ(2u, dispatcher
->requests_
.size());
383 dispatcher
->CancelGenerateStream(kRequestId2
);
384 EXPECT_EQ(1u, dispatcher
->requests_
.size());
386 // Complete the creation of stream1.
387 StreamDeviceInfo audio_device_info
;
388 audio_device_info
.device
.name
= "Microphone";
389 audio_device_info
.device
.type
= kAudioType
;
390 audio_device_info
.session_id
= kAudioSessionId
;
391 StreamDeviceInfoArray
audio_device_array(1);
392 audio_device_array
[0] = audio_device_info
;
394 StreamDeviceInfo video_device_info
;
395 video_device_info
.device
.name
= "Camera";
396 video_device_info
.device
.type
= kVideoType
;
397 video_device_info
.session_id
= kVideoSessionId
;
398 StreamDeviceInfoArray
video_device_array(1);
399 video_device_array
[0] = video_device_info
;
401 std::string stream_label1
= "stream1";
402 dispatcher
->OnMessageReceived(MediaStreamMsg_StreamGenerated(
403 kRouteId
, ipc_request_id1
, stream_label1
,
404 audio_device_array
, video_device_array
));
405 EXPECT_EQ(handler
->request_id_
, kRequestId1
);
406 EXPECT_EQ(handler
->label_
, stream_label1
);
407 EXPECT_EQ(0u, dispatcher
->requests_
.size());
410 } // namespace content