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.
9 #include "base/callback_helpers.h"
10 #include "base/command_line.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
15 #include "content/browser/renderer_host/media/media_stream_manager.h"
16 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
17 #include "content/browser/renderer_host/media/video_capture_manager.h"
18 #include "content/common/media/media_stream_messages.h"
19 #include "content/common/media/media_stream_options.h"
20 #include "content/public/browser/media_device_id.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/test/mock_resource_context.h"
23 #include "content/public/test/test_browser_context.h"
24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "content/test/test_content_browser_client.h"
26 #include "content/test/test_content_client.h"
27 #include "ipc/ipc_message_macros.h"
28 #include "media/audio/mock_audio_manager.h"
29 #include "media/video/capture/fake_video_capture_device_factory.h"
30 #include "net/url_request/url_request_context.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
35 using ::testing::DeleteArg
;
36 using ::testing::DoAll
;
37 using ::testing::Return
;
38 using ::testing::SaveArg
;
40 const int kProcessId
= 5;
41 const int kRenderId
= 6;
42 const int kPageRequestId
= 7;
46 class MockMediaStreamDispatcherHost
: public MediaStreamDispatcherHost
,
47 public TestContentBrowserClient
{
49 MockMediaStreamDispatcherHost(
50 const ResourceContext::SaltCallback salt_callback
,
51 const scoped_refptr
<base::MessageLoopProxy
>& message_loop
,
52 MediaStreamManager
* manager
)
53 : MediaStreamDispatcherHost(kProcessId
, salt_callback
, manager
),
54 message_loop_(message_loop
) {}
56 // A list of mock methods.
57 MOCK_METHOD4(OnStreamGenerated
,
58 void(int routing_id
, int request_id
, int audio_array_size
,
59 int video_array_size
));
60 MOCK_METHOD3(OnStreamGenerationFailed
, void(int routing_id
,
62 MediaStreamRequestResult result
));
63 MOCK_METHOD1(OnDeviceStopped
, void(int routing_id
));
64 MOCK_METHOD2(OnDeviceOpened
, void(int routing_id
, int request_id
));
66 // Accessor to private functions.
67 void OnGenerateStream(int render_view_id
,
69 const StreamOptions
& components
,
70 const GURL
& security_origin
,
71 const base::Closure
& quit_closure
) {
72 quit_closures_
.push(quit_closure
);
73 MediaStreamDispatcherHost::OnGenerateStream(
74 render_view_id
, page_request_id
, components
, security_origin
, false);
77 void OnStopStreamDevice(int render_view_id
,
78 const std::string
& device_id
) {
79 MediaStreamDispatcherHost::OnStopStreamDevice(render_view_id
, device_id
);
82 void OnOpenDevice(int render_view_id
,
84 const std::string
& device_id
,
86 const GURL
& security_origin
,
87 const base::Closure
& quit_closure
) {
88 quit_closures_
.push(quit_closure
);
89 MediaStreamDispatcherHost::OnOpenDevice(
90 render_view_id
, page_request_id
, device_id
, type
, security_origin
);
93 void OnEnumerateDevices(int render_view_id
,
96 const GURL
& security_origin
,
97 const base::Closure
& quit_closure
) {
98 quit_closures_
.push(quit_closure
);
99 MediaStreamDispatcherHost::OnEnumerateDevices(
100 render_view_id
, page_request_id
, type
, security_origin
);
104 StreamDeviceInfoArray audio_devices_
;
105 StreamDeviceInfoArray video_devices_
;
106 StreamDeviceInfo opened_device_
;
107 StreamDeviceInfoArray enumerated_devices_
;
110 virtual ~MockMediaStreamDispatcherHost() {}
112 // This method is used to dispatch IPC messages to the renderer. We intercept
113 // these messages here and dispatch to our mock methods to verify the
114 // conversation between this object and the renderer.
115 virtual bool Send(IPC::Message
* message
) OVERRIDE
{
118 // In this method we dispatch the messages to the according handlers as if
119 // we are the renderer.
121 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost
, *message
)
122 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated
, OnStreamGenerated
)
123 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed
,
124 OnStreamGenerationFailed
)
125 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped
, OnDeviceStopped
)
126 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened
, OnDeviceOpened
)
127 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated
,
129 IPC_MESSAGE_UNHANDLED(handled
= false)
130 IPC_END_MESSAGE_MAP()
131 EXPECT_TRUE(handled
);
137 // These handler methods do minimal things and delegate to the mock methods.
138 void OnStreamGenerated(
139 const IPC::Message
& msg
,
142 StreamDeviceInfoArray audio_device_list
,
143 StreamDeviceInfoArray video_device_list
) {
144 OnStreamGenerated(msg
.routing_id(), request_id
, audio_device_list
.size(),
145 video_device_list
.size());
146 // Notify that the event have occurred.
147 base::Closure quit_closure
= quit_closures_
.front();
148 quit_closures_
.pop();
149 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
152 audio_devices_
= audio_device_list
;
153 video_devices_
= video_device_list
;
156 void OnStreamGenerationFailed(
157 const IPC::Message
& msg
,
159 content::MediaStreamRequestResult result
) {
160 OnStreamGenerationFailed(msg
.routing_id(), request_id
, result
);
161 if (!quit_closures_
.empty()) {
162 base::Closure quit_closure
= quit_closures_
.front();
163 quit_closures_
.pop();
164 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
170 void OnDeviceStopped(const IPC::Message
& msg
,
171 const std::string
& label
,
172 const content::StreamDeviceInfo
& device
) {
173 if (IsVideoMediaType(device
.device
.type
))
174 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, video_devices_
[0]));
175 if (IsAudioMediaType(device
.device
.type
))
176 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, audio_devices_
[0]));
178 OnDeviceStopped(msg
.routing_id());
181 void OnDeviceOpened(const IPC::Message
& msg
,
183 const std::string
& label
,
184 const StreamDeviceInfo
& device
) {
185 base::Closure quit_closure
= quit_closures_
.front();
186 quit_closures_
.pop();
187 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
189 opened_device_
= device
;
192 void OnDevicesEnumerated(const IPC::Message
& msg
,
194 const StreamDeviceInfoArray
& devices
) {
195 base::Closure quit_closure
= quit_closures_
.front();
196 quit_closures_
.pop();
197 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
198 enumerated_devices_
= devices
;
201 scoped_refptr
<base::MessageLoopProxy
> message_loop_
;
203 std::queue
<base::Closure
> quit_closures_
;
206 class MockMediaStreamUIProxy
: public FakeMediaStreamUIProxy
{
210 void(const base::Closure
& stop
,
211 const MediaStreamUIProxy::WindowIdCallback
& window_id_callback
));
214 class MediaStreamDispatcherHostTest
: public testing::Test
{
216 MediaStreamDispatcherHostTest()
217 : old_browser_client_(NULL
),
218 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
219 origin_("https://test.com") {
220 audio_manager_
.reset(
221 new media::MockAudioManager(base::MessageLoopProxy::current()));
222 // Make sure we use fake devices to avoid long delays.
223 CommandLine::ForCurrentProcess()->AppendSwitch(
224 switches::kUseFakeDeviceForMediaStream
);
225 // Create our own MediaStreamManager.
226 media_stream_manager_
.reset(new MediaStreamManager(audio_manager_
.get()));
227 video_capture_device_factory_
=
228 static_cast<media::FakeVideoCaptureDeviceFactory
*>(
229 media_stream_manager_
->video_capture_manager()
230 ->video_capture_device_factory());
231 DCHECK(video_capture_device_factory_
);
233 host_
= new MockMediaStreamDispatcherHost(
234 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
235 base::MessageLoopProxy::current(),
236 media_stream_manager_
.get());
238 // Use the fake content client and browser.
239 content_client_
.reset(new TestContentClient());
240 SetContentClient(content_client_
.get());
241 old_browser_client_
= SetBrowserClientForTesting(host_
.get());
244 virtual ~MediaStreamDispatcherHostTest() {
247 virtual void SetUp() OVERRIDE
{
248 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
249 ASSERT_GT(physical_video_devices_
.size(), 0u);
251 audio_manager_
->GetAudioInputDeviceNames(&physical_audio_devices_
);
252 ASSERT_GT(physical_audio_devices_
.size(), 0u);
255 virtual void TearDown() OVERRIDE
{
256 host_
->OnChannelClosing();
260 virtual void SetupFakeUI(bool expect_started
) {
261 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
262 if (expect_started
) {
263 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
));
265 media_stream_manager_
->UseFakeUI(
266 stream_ui
.PassAs
<FakeMediaStreamUIProxy
>());
269 void GenerateStreamAndWaitForResult(int render_view_id
,
271 const StreamOptions
& options
) {
272 base::RunLoop run_loop
;
273 int expected_audio_array_size
=
274 (options
.audio_requested
&&
275 physical_audio_devices_
.size() > 0) ? 1 : 0;
276 int expected_video_array_size
=
277 (options
.video_requested
&&
278 physical_video_devices_
.size() > 0) ? 1 : 0;
279 EXPECT_CALL(*host_
.get(), OnStreamGenerated(render_view_id
, page_request_id
,
280 expected_audio_array_size
,
281 expected_video_array_size
));
282 host_
->OnGenerateStream(render_view_id
, page_request_id
, options
, origin_
,
283 run_loop
.QuitClosure());
285 EXPECT_FALSE(DoesContainRawIds(host_
->audio_devices_
));
286 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
287 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->audio_devices_
, origin_
));
288 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
291 void GenerateStreamAndWaitForFailure(
294 const StreamOptions
& options
,
295 MediaStreamRequestResult expected_result
) {
296 base::RunLoop run_loop
;
297 EXPECT_CALL(*host_
.get(),
298 OnStreamGenerationFailed(render_view_id
,
301 host_
->OnGenerateStream(render_view_id
, page_request_id
, options
, origin_
,
302 run_loop
.QuitClosure());
306 void OpenVideoDeviceAndWaitForResult(int render_view_id
,
308 const std::string
& device_id
) {
309 base::RunLoop run_loop
;
310 host_
->OnOpenDevice(render_view_id
, page_request_id
, device_id
,
311 MEDIA_DEVICE_VIDEO_CAPTURE
, origin_
,
312 run_loop
.QuitClosure());
314 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
315 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
318 void EnumerateDevicesAndWaitForResult(int render_view_id
,
320 MediaStreamType type
) {
321 base::RunLoop run_loop
;
322 host_
->OnEnumerateDevices(render_view_id
, page_request_id
, type
, origin_
,
323 run_loop
.QuitClosure());
325 ASSERT_FALSE(host_
->enumerated_devices_
.empty());
326 EXPECT_FALSE(DoesContainRawIds(host_
->enumerated_devices_
));
327 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->enumerated_devices_
, origin_
));
330 bool DoesContainRawIds(const StreamDeviceInfoArray
& devices
) {
331 for (size_t i
= 0; i
< devices
.size(); ++i
) {
332 media::AudioDeviceNames::const_iterator audio_it
=
333 physical_audio_devices_
.begin();
334 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
335 if (audio_it
->unique_id
== devices
[i
].device
.id
)
338 media::VideoCaptureDevice::Names::const_iterator video_it
=
339 physical_video_devices_
.begin();
340 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
341 if (video_it
->id() == devices
[i
].device
.id
)
348 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray
& devices
,
349 const GURL
& origin
) {
350 for (size_t i
= 0; i
< devices
.size(); ++i
) {
351 bool found_match
= false;
352 media::AudioDeviceNames::const_iterator audio_it
=
353 physical_audio_devices_
.begin();
354 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
355 if (content::DoesMediaDeviceIDMatchHMAC(
356 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
358 devices
[i
].device
.id
,
359 audio_it
->unique_id
)) {
360 EXPECT_FALSE(found_match
);
364 media::VideoCaptureDevice::Names::const_iterator video_it
=
365 physical_video_devices_
.begin();
366 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
367 if (content::DoesMediaDeviceIDMatchHMAC(
368 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
370 devices
[i
].device
.id
,
372 EXPECT_FALSE(found_match
);
382 void AddSourceIdConstraint(const std::string
& source_id
,
383 StreamOptions::Constraints
* constraints
) {
384 constraints
->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId
,
388 scoped_refptr
<MockMediaStreamDispatcherHost
> host_
;
389 scoped_ptr
<media::AudioManager
> audio_manager_
;
390 scoped_ptr
<MediaStreamManager
> media_stream_manager_
;
391 ContentBrowserClient
* old_browser_client_
;
392 scoped_ptr
<ContentClient
> content_client_
;
393 content::TestBrowserThreadBundle thread_bundle_
;
394 content::TestBrowserContext browser_context_
;
395 media::AudioDeviceNames physical_audio_devices_
;
396 media::VideoCaptureDevice::Names physical_video_devices_
;
398 media::FakeVideoCaptureDeviceFactory
* video_capture_device_factory_
;
401 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithVideoOnly
) {
402 StreamOptions
options(false, true);
405 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
407 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
408 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
411 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioOnly
) {
412 StreamOptions
options(true, false);
415 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
417 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
418 EXPECT_EQ(host_
->video_devices_
.size(), 0u);
421 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithNothing
) {
422 StreamOptions
options(false, false);
424 GenerateStreamAndWaitForFailure(
428 MEDIA_DEVICE_INVALID_STATE
);
431 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioAndVideo
) {
432 StreamOptions
options(true, true);
435 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
437 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
438 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
441 // This test generates two streams with video only using the same render view
442 // id. The same capture device with the same device and session id is expected
444 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsFromSameRenderId
) {
445 StreamOptions
options(false, true);
447 // Generate first stream.
449 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
451 // Check the latest generated stream.
452 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
453 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
454 const std::string label1
= host_
->label_
;
455 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
456 const int session_id1
= host_
->video_devices_
.front().session_id
;
458 // Generate second stream.
460 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ 1, options
);
462 // Check the latest generated stream.
463 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
464 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
465 const std::string label2
= host_
->label_
;
466 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
467 int session_id2
= host_
->video_devices_
.front().session_id
;
468 EXPECT_EQ(device_id1
, device_id2
);
469 EXPECT_EQ(session_id1
, session_id2
);
470 EXPECT_NE(label1
, label2
);
473 TEST_F(MediaStreamDispatcherHostTest
,
474 GenerateStreamAndOpenDeviceFromSameRenderId
) {
475 StreamOptions
options(false, true);
477 // Generate first stream.
479 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
481 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
482 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
483 const std::string label1
= host_
->label_
;
484 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
485 const int session_id1
= host_
->video_devices_
.front().session_id
;
487 // Generate second stream.
488 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
, device_id1
);
490 const std::string device_id2
= host_
->opened_device_
.device
.id
;
491 const int session_id2
= host_
->opened_device_
.session_id
;
492 const std::string label2
= host_
->label_
;
494 EXPECT_EQ(device_id1
, device_id2
);
495 EXPECT_NE(session_id1
, session_id2
);
496 EXPECT_NE(label1
, label2
);
500 // This test generates two streams with video only using two separate render
501 // view ids. The same device id but different session ids are expected.
502 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsDifferentRenderId
) {
503 StreamOptions
options(false, true);
505 // Generate first stream.
507 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
509 // Check the latest generated stream.
510 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
511 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
512 const std::string label1
= host_
->label_
;
513 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
514 const int session_id1
= host_
->video_devices_
.front().session_id
;
516 // Generate second stream from another render view.
518 GenerateStreamAndWaitForResult(kRenderId
+1, kPageRequestId
+ 1, options
);
520 // Check the latest generated stream.
521 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
522 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
523 const std::string label2
= host_
->label_
;
524 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
525 const int session_id2
= host_
->video_devices_
.front().session_id
;
526 EXPECT_EQ(device_id1
, device_id2
);
527 EXPECT_NE(session_id1
, session_id2
);
528 EXPECT_NE(label1
, label2
);
531 // This test request two streams with video only without waiting for the first
532 // stream to be generated before requesting the second.
533 // The same device id and session ids are expected.
534 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithoutWaiting
) {
535 StreamOptions
options(false, true);
537 // Generate first stream.
539 EXPECT_CALL(*host_
.get(), OnStreamGenerated(kRenderId
, kPageRequestId
, 0, 1));
541 // Generate second stream.
542 EXPECT_CALL(*host_
.get(),
543 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
545 base::RunLoop run_loop1
;
546 base::RunLoop run_loop2
;
547 host_
->OnGenerateStream(kRenderId
, kPageRequestId
, options
, origin_
,
548 run_loop1
.QuitClosure());
549 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
550 run_loop2
.QuitClosure());
556 // Test that we can generate streams where a mandatory sourceId is specified in
558 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithMandatorySourceId
) {
559 ASSERT_GE(physical_audio_devices_
.size(), 1u);
560 ASSERT_GE(physical_video_devices_
.size(), 1u);
562 media::AudioDeviceNames::const_iterator audio_it
=
563 physical_audio_devices_
.begin();
564 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
565 std::string source_id
= content::GetHMACForMediaDeviceID(
566 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
568 audio_it
->unique_id
);
569 ASSERT_FALSE(source_id
.empty());
570 StreamOptions
options(true, true);
571 AddSourceIdConstraint(source_id
, &options
.mandatory_audio
);
574 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
575 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
578 media::VideoCaptureDevice::Names::const_iterator video_it
=
579 physical_video_devices_
.begin();
580 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
581 std::string source_id
= content::GetHMACForMediaDeviceID(
582 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
585 ASSERT_FALSE(source_id
.empty());
586 StreamOptions
options(true, true);
587 AddSourceIdConstraint(source_id
, &options
.mandatory_video
);
590 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
591 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
595 // Test that we can generate streams where a optional sourceId is specified in
597 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithOptionalSourceId
) {
598 ASSERT_GE(physical_audio_devices_
.size(), 1u);
599 ASSERT_GE(physical_video_devices_
.size(), 1u);
601 media::AudioDeviceNames::const_iterator audio_it
=
602 physical_audio_devices_
.begin();
603 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
604 std::string source_id
= content::GetHMACForMediaDeviceID(
605 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
607 audio_it
->unique_id
);
608 ASSERT_FALSE(source_id
.empty());
609 StreamOptions
options(true, true);
610 AddSourceIdConstraint(source_id
, &options
.optional_audio
);
613 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
614 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
617 media::VideoCaptureDevice::Names::const_iterator video_it
=
618 physical_video_devices_
.begin();
619 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
620 std::string source_id
= content::GetHMACForMediaDeviceID(
621 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
624 ASSERT_FALSE(source_id
.empty());
625 StreamOptions
options(true, true);
626 AddSourceIdConstraint(source_id
, &options
.optional_video
);
629 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
630 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
634 // Test that generating a stream with an invalid mandatory video source id fail.
635 TEST_F(MediaStreamDispatcherHostTest
,
636 GenerateStreamsWithInvalidMandatoryVideoSourceId
) {
637 StreamOptions
options(true, true);
638 AddSourceIdConstraint("invalid source id", &options
.mandatory_video
);
640 GenerateStreamAndWaitForFailure(
644 MEDIA_DEVICE_NO_HARDWARE
);
647 // Test that generating a stream with an invalid mandatory audio source id fail.
648 TEST_F(MediaStreamDispatcherHostTest
,
649 GenerateStreamsWithInvalidMandatoryAudioSourceId
) {
650 StreamOptions
options(true, true);
651 AddSourceIdConstraint("invalid source id", &options
.mandatory_audio
);
653 GenerateStreamAndWaitForFailure(
657 MEDIA_DEVICE_NO_HARDWARE
);
660 // Test that generating a stream with an invalid optional video source id
662 TEST_F(MediaStreamDispatcherHostTest
,
663 GenerateStreamsWithInvalidOptionalVideoSourceId
) {
664 StreamOptions
options(true, true);
665 AddSourceIdConstraint("invalid source id", &options
.optional_video
);
668 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
671 // Test that generating a stream with an invalid optional audio source id
673 TEST_F(MediaStreamDispatcherHostTest
,
674 GenerateStreamsWithInvalidOptionalAudioSourceId
) {
675 StreamOptions
options(true, true);
676 AddSourceIdConstraint("invalid source id", &options
.optional_audio
);
679 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
682 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsNoAvailableVideoDevice
) {
683 physical_video_devices_
.clear();
684 video_capture_device_factory_
->set_number_of_devices(0);
685 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
686 StreamOptions
options(true, true);
689 GenerateStreamAndWaitForFailure(kRenderId
, kPageRequestId
, options
,
690 MEDIA_DEVICE_NO_HARDWARE
);
693 // Test that if a OnStopStreamDevice message is received for a device that has
694 // been opened in a MediaStream and by pepper, the device is only stopped for
696 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStream
) {
697 StreamOptions
options(false, true);
700 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
702 std::string stream_request_label
= host_
->label_
;
703 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
704 ASSERT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
705 stream_request_label
).size());
707 // Open the same device by Pepper.
708 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
,
709 video_device_info
.device
.id
);
710 std::string open_device_request_label
= host_
->label_
;
712 // Stop the device in the MediaStream.
713 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
715 EXPECT_EQ(0u, media_stream_manager_
->GetDevicesOpenedByRequest(
716 stream_request_label
).size());
717 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
718 open_device_request_label
).size());
721 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStreamAndRestart
) {
722 StreamOptions
options(true, true);
725 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
727 std::string request_label1
= host_
->label_
;
728 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
729 // Expect that 1 audio and 1 video device has been opened.
730 EXPECT_EQ(2u, media_stream_manager_
->GetDevicesOpenedByRequest(
731 request_label1
).size());
733 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
734 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
735 request_label1
).size());
737 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
738 std::string request_label2
= host_
->label_
;
740 StreamDeviceInfoArray request1_devices
=
741 media_stream_manager_
->GetDevicesOpenedByRequest(request_label1
);
742 StreamDeviceInfoArray request2_devices
=
743 media_stream_manager_
->GetDevicesOpenedByRequest(request_label2
);
745 ASSERT_EQ(1u, request1_devices
.size());
746 ASSERT_EQ(2u, request2_devices
.size());
748 // Test that the same audio device has been opened in both streams.
749 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices
[0],
750 request2_devices
[0]) ||
751 StreamDeviceInfo::IsEqual(request1_devices
[0],
752 request2_devices
[1]));
755 TEST_F(MediaStreamDispatcherHostTest
,
756 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream
) {
757 StreamOptions
options(false, true);
760 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
761 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
763 // Generate a second stream.
764 EXPECT_CALL(*host_
.get(),
765 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
767 base::RunLoop run_loop1
;
768 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
769 run_loop1
.QuitClosure());
771 // Stop the video stream device from stream 1 while waiting for the
772 // second stream to be generated.
773 host_
->OnStopStreamDevice(kRenderId
, host_
->video_devices_
[0].device
.id
);
776 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
779 TEST_F(MediaStreamDispatcherHostTest
, CancelPendingStreamsOnChannelClosing
) {
780 StreamOptions
options(false, true);
782 base::RunLoop run_loop
;
784 // Create multiple GenerateStream requests.
786 for (size_t i
= 1; i
<= streams
; ++i
) {
787 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ i
, options
, origin_
,
788 run_loop
.QuitClosure());
791 // Calling OnChannelClosing() to cancel all the pending requests.
792 host_
->OnChannelClosing();
793 run_loop
.RunUntilIdle();
796 TEST_F(MediaStreamDispatcherHostTest
, StopGeneratedStreamsOnChannelClosing
) {
797 StreamOptions
options(false, true);
799 // Create first group of streams.
800 size_t generated_streams
= 3;
801 for (size_t i
= 0; i
< generated_streams
; ++i
) {
803 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ i
, options
);
806 // Calling OnChannelClosing() to cancel all the pending/generated streams.
807 host_
->OnChannelClosing();
808 base::RunLoop().RunUntilIdle();
811 TEST_F(MediaStreamDispatcherHostTest
, CloseFromUI
) {
812 StreamOptions
options(false, true);
814 base::Closure close_callback
;
815 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
816 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
))
817 .WillOnce(SaveArg
<0>(&close_callback
));
818 media_stream_manager_
->UseFakeUI(stream_ui
.PassAs
<FakeMediaStreamUIProxy
>());
820 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
822 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
823 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
825 ASSERT_FALSE(close_callback
.is_null());
826 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
));
827 close_callback
.Run();
828 base::RunLoop().RunUntilIdle();
831 // Test that the dispatcher is notified if a video device that is in use is
833 TEST_F(MediaStreamDispatcherHostTest
, VideoDeviceUnplugged
) {
834 StreamOptions
options(true, true);
836 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
837 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
838 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
840 video_capture_device_factory_
->set_number_of_devices(0);
842 base::RunLoop run_loop
;
843 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
))
844 .WillOnce(testing::InvokeWithoutArgs(&run_loop
, &base::RunLoop::Quit
));
845 media_stream_manager_
->OnDevicesChanged(
846 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE
);
851 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevices
) {
852 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
853 MEDIA_DEVICE_AUDIO_CAPTURE
);
856 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevices
) {
857 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
858 MEDIA_DEVICE_VIDEO_CAPTURE
);
861 }; // namespace content