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/audio_input_device_manager.h"
15 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
16 #include "content/browser/renderer_host/media/media_stream_manager.h"
17 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
18 #include "content/browser/renderer_host/media/video_capture_manager.h"
19 #include "content/common/media/media_stream_messages.h"
20 #include "content/common/media/media_stream_options.h"
21 #include "content/public/browser/media_device_id.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/mock_resource_context.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "content/test/test_content_browser_client.h"
27 #include "content/test/test_content_client.h"
28 #include "ipc/ipc_message_macros.h"
29 #include "media/audio/mock_audio_manager.h"
30 #include "media/base/media_switches.h"
31 #include "media/video/capture/fake_video_capture_device_factory.h"
32 #include "net/url_request/url_request_context.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
37 using ::testing::DeleteArg
;
38 using ::testing::DoAll
;
39 using ::testing::InSequence
;
40 using ::testing::Return
;
41 using ::testing::SaveArg
;
43 const int kProcessId
= 5;
44 const int kRenderId
= 6;
45 const int kPageRequestId
= 7;
49 class MockMediaStreamDispatcherHost
: public MediaStreamDispatcherHost
,
50 public TestContentBrowserClient
{
52 MockMediaStreamDispatcherHost(
53 const ResourceContext::SaltCallback salt_callback
,
54 const scoped_refptr
<base::MessageLoopProxy
>& message_loop
,
55 MediaStreamManager
* manager
)
56 : MediaStreamDispatcherHost(kProcessId
, salt_callback
, manager
),
57 message_loop_(message_loop
),
60 // A list of mock methods.
61 MOCK_METHOD4(OnStreamGenerated
,
62 void(int routing_id
, int request_id
, int audio_array_size
,
63 int video_array_size
));
64 MOCK_METHOD3(OnStreamGenerationFailed
, void(int routing_id
,
66 MediaStreamRequestResult result
));
67 MOCK_METHOD1(OnDeviceStopped
, void(int routing_id
));
68 MOCK_METHOD2(OnDeviceOpened
, void(int routing_id
, int request_id
));
70 // Accessor to private functions.
71 void OnGenerateStream(int render_frame_id
,
73 const StreamOptions
& components
,
74 const GURL
& security_origin
,
75 const base::Closure
& quit_closure
) {
76 quit_closures_
.push(quit_closure
);
77 MediaStreamDispatcherHost::OnGenerateStream(
78 render_frame_id
, page_request_id
, components
, security_origin
, false);
81 void OnStopStreamDevice(int render_frame_id
,
82 const std::string
& device_id
) {
83 MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id
, device_id
);
86 void OnOpenDevice(int render_frame_id
,
88 const std::string
& device_id
,
90 const GURL
& security_origin
,
91 const base::Closure
& quit_closure
) {
92 quit_closures_
.push(quit_closure
);
93 MediaStreamDispatcherHost::OnOpenDevice(
94 render_frame_id
, page_request_id
, device_id
, type
, security_origin
);
97 void OnEnumerateDevices(int render_frame_id
,
100 const GURL
& security_origin
,
101 const base::Closure
& quit_closure
) {
102 quit_closures_
.push(quit_closure
);
103 MediaStreamDispatcherHost::OnEnumerateDevices(
104 render_frame_id
, page_request_id
, type
, security_origin
);
108 StreamDeviceInfoArray audio_devices_
;
109 StreamDeviceInfoArray video_devices_
;
110 StreamDeviceInfo opened_device_
;
111 StreamDeviceInfoArray enumerated_devices_
;
114 virtual ~MockMediaStreamDispatcherHost() {}
116 // This method is used to dispatch IPC messages to the renderer. We intercept
117 // these messages here and dispatch to our mock methods to verify the
118 // conversation between this object and the renderer.
119 virtual bool Send(IPC::Message
* message
) OVERRIDE
{
121 current_ipc_
= message
;
123 // In this method we dispatch the messages to the according handlers as if
124 // we are the renderer.
126 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost
, *message
)
127 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated
,
128 OnStreamGeneratedInternal
)
129 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed
,
130 OnStreamGenerationFailedInternal
)
131 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped
, OnDeviceStoppedInternal
)
132 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened
, OnDeviceOpenedInternal
)
133 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated
, OnDevicesEnumerated
)
134 IPC_MESSAGE_UNHANDLED(handled
= false)
135 IPC_END_MESSAGE_MAP()
136 EXPECT_TRUE(handled
);
143 // These handler methods do minimal things and delegate to the mock methods.
144 void OnStreamGeneratedInternal(
147 StreamDeviceInfoArray audio_device_list
,
148 StreamDeviceInfoArray video_device_list
) {
149 OnStreamGenerated(current_ipc_
->routing_id(), request_id
,
150 audio_device_list
.size(), video_device_list
.size());
151 // Notify that the event have occurred.
152 base::Closure quit_closure
= quit_closures_
.front();
153 quit_closures_
.pop();
154 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
157 audio_devices_
= audio_device_list
;
158 video_devices_
= video_device_list
;
161 void OnStreamGenerationFailedInternal(
163 content::MediaStreamRequestResult result
) {
164 OnStreamGenerationFailed(current_ipc_
->routing_id(), request_id
, result
);
165 if (!quit_closures_
.empty()) {
166 base::Closure quit_closure
= quit_closures_
.front();
167 quit_closures_
.pop();
168 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
174 void OnDeviceStoppedInternal(const std::string
& label
,
175 const content::StreamDeviceInfo
& device
) {
176 if (IsVideoMediaType(device
.device
.type
))
177 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, video_devices_
[0]));
178 if (IsAudioInputMediaType(device
.device
.type
))
179 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, audio_devices_
[0]));
181 OnDeviceStopped(current_ipc_
->routing_id());
184 void OnDeviceOpenedInternal(int request_id
,
185 const std::string
& label
,
186 const StreamDeviceInfo
& device
) {
187 base::Closure quit_closure
= quit_closures_
.front();
188 quit_closures_
.pop();
189 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
191 opened_device_
= device
;
194 void OnDevicesEnumerated(int request_id
,
195 const StreamDeviceInfoArray
& devices
) {
196 base::Closure quit_closure
= quit_closures_
.front();
197 quit_closures_
.pop();
198 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
199 enumerated_devices_
= devices
;
202 scoped_refptr
<base::MessageLoopProxy
> message_loop_
;
203 IPC::Message
* current_ipc_
;
204 std::queue
<base::Closure
> quit_closures_
;
207 class MockMediaStreamUIProxy
: public FakeMediaStreamUIProxy
{
211 void(const base::Closure
& stop
,
212 const MediaStreamUIProxy::WindowIdCallback
& window_id_callback
));
215 class MediaStreamManagerForTest
: public MediaStreamManager
{
217 MediaStreamManagerForTest(media::AudioManager
* audio_manager
)
218 : MediaStreamManager(audio_manager
),
220 camera_access_(true) {}
222 virtual ~MediaStreamManagerForTest() {}
224 void set_mic_access(bool allow_access
) {
225 mic_access_
= allow_access
;
228 void set_camera_access(bool allow_access
) {
229 camera_access_
= allow_access
;
233 virtual bool CheckMediaAccessPermissionOnUIThread(
234 int render_process_id
,
235 const GURL
& security_origin
,
236 MediaStreamType type
) OVERRIDE
{
237 if (type
== MEDIA_DEVICE_AUDIO_CAPTURE
)
239 else if (type
== MEDIA_DEVICE_VIDEO_CAPTURE
)
240 return camera_access_
;
248 class MediaStreamDispatcherHostTest
: public testing::Test
{
250 MediaStreamDispatcherHostTest()
251 : old_browser_client_(NULL
),
252 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
253 origin_("https://test.com") {
254 audio_manager_
.reset(
255 new media::MockAudioManager(base::MessageLoopProxy::current()));
256 // Make sure we use fake devices to avoid long delays.
257 base::CommandLine::ForCurrentProcess()->AppendSwitch(
258 switches::kUseFakeDeviceForMediaStream
);
259 // Create our own MediaStreamManager.
260 media_stream_manager_
.reset(
261 new MediaStreamManagerForTest(audio_manager_
.get()));
262 video_capture_device_factory_
=
263 static_cast<media::FakeVideoCaptureDeviceFactory
*>(
264 media_stream_manager_
->video_capture_manager()
265 ->video_capture_device_factory());
266 DCHECK(video_capture_device_factory_
);
268 MockResourceContext
* mock_resource_context
=
269 static_cast<MockResourceContext
*>(
270 browser_context_
.GetResourceContext());
272 host_
= new MockMediaStreamDispatcherHost(
273 mock_resource_context
->GetMediaDeviceIDSalt(),
274 base::MessageLoopProxy::current(),
275 media_stream_manager_
.get());
277 // Use the fake content client and browser.
278 content_client_
.reset(new TestContentClient());
279 SetContentClient(content_client_
.get());
280 old_browser_client_
= SetBrowserClientForTesting(host_
.get());
283 virtual ~MediaStreamDispatcherHostTest() {
286 virtual void SetUp() OVERRIDE
{
287 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
288 ASSERT_GT(physical_video_devices_
.size(), 0u);
290 media_stream_manager_
->audio_input_device_manager()->GetFakeDeviceNames(
291 &physical_audio_devices_
);
292 ASSERT_GT(physical_audio_devices_
.size(), 0u);
295 virtual void TearDown() OVERRIDE
{
296 host_
->OnChannelClosing();
300 virtual void SetupFakeUI(bool expect_started
) {
301 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
302 if (expect_started
) {
303 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
));
305 media_stream_manager_
->UseFakeUI(
306 stream_ui
.PassAs
<FakeMediaStreamUIProxy
>());
309 void GenerateStreamAndWaitForResult(int render_frame_id
,
311 const StreamOptions
& options
) {
312 base::RunLoop run_loop
;
313 int expected_audio_array_size
=
314 (options
.audio_requested
&&
315 physical_audio_devices_
.size() > 0) ? 1 : 0;
316 int expected_video_array_size
=
317 (options
.video_requested
&&
318 physical_video_devices_
.size() > 0) ? 1 : 0;
319 EXPECT_CALL(*host_
.get(), OnStreamGenerated(render_frame_id
,
321 expected_audio_array_size
,
322 expected_video_array_size
));
323 host_
->OnGenerateStream(render_frame_id
, page_request_id
, options
, origin_
,
324 run_loop
.QuitClosure());
326 EXPECT_FALSE(DoesContainRawIds(host_
->audio_devices_
));
327 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
328 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->audio_devices_
, origin_
));
329 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
332 void GenerateStreamAndWaitForFailure(
335 const StreamOptions
& options
,
336 MediaStreamRequestResult expected_result
) {
337 base::RunLoop run_loop
;
338 EXPECT_CALL(*host_
.get(),
339 OnStreamGenerationFailed(render_frame_id
,
342 host_
->OnGenerateStream(render_frame_id
, page_request_id
, options
,
343 origin_
, run_loop
.QuitClosure());
347 void OpenVideoDeviceAndWaitForResult(int render_frame_id
,
349 const std::string
& device_id
) {
350 base::RunLoop run_loop
;
351 host_
->OnOpenDevice(render_frame_id
, page_request_id
, device_id
,
352 MEDIA_DEVICE_VIDEO_CAPTURE
, origin_
,
353 run_loop
.QuitClosure());
355 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
356 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
359 void EnumerateDevicesAndWaitForResult(int render_frame_id
,
361 MediaStreamType type
) {
362 base::RunLoop run_loop
;
363 host_
->OnEnumerateDevices(render_frame_id
, page_request_id
, type
, origin_
,
364 run_loop
.QuitClosure());
366 ASSERT_FALSE(host_
->enumerated_devices_
.empty());
367 EXPECT_FALSE(DoesContainRawIds(host_
->enumerated_devices_
));
368 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->enumerated_devices_
, origin_
));
371 bool DoesContainRawIds(const StreamDeviceInfoArray
& devices
) {
372 for (size_t i
= 0; i
< devices
.size(); ++i
) {
373 media::AudioDeviceNames::const_iterator audio_it
=
374 physical_audio_devices_
.begin();
375 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
376 if (audio_it
->unique_id
== devices
[i
].device
.id
)
379 media::VideoCaptureDevice::Names::const_iterator video_it
=
380 physical_video_devices_
.begin();
381 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
382 if (video_it
->id() == devices
[i
].device
.id
)
389 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray
& devices
,
390 const GURL
& origin
) {
391 for (size_t i
= 0; i
< devices
.size(); ++i
) {
392 bool found_match
= false;
393 media::AudioDeviceNames::const_iterator audio_it
=
394 physical_audio_devices_
.begin();
395 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
396 if (content::DoesMediaDeviceIDMatchHMAC(
397 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
399 devices
[i
].device
.id
,
400 audio_it
->unique_id
)) {
401 EXPECT_FALSE(found_match
);
405 media::VideoCaptureDevice::Names::const_iterator video_it
=
406 physical_video_devices_
.begin();
407 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
408 if (content::DoesMediaDeviceIDMatchHMAC(
409 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
411 devices
[i
].device
.id
,
413 EXPECT_FALSE(found_match
);
423 // Returns true if all devices have labels, false otherwise.
424 bool DoesContainLabels(const StreamDeviceInfoArray
& devices
) {
425 for (size_t i
= 0; i
< devices
.size(); ++i
) {
426 if (devices
[i
].device
.name
.empty())
432 // Returns true if no devices have labels, false otherwise.
433 bool DoesNotContainLabels(const StreamDeviceInfoArray
& devices
) {
434 for (size_t i
= 0; i
< devices
.size(); ++i
) {
435 if (!devices
[i
].device
.name
.empty())
441 void AddSourceIdConstraint(const std::string
& source_id
,
442 StreamOptions::Constraints
* constraints
) {
443 constraints
->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId
,
447 scoped_refptr
<MockMediaStreamDispatcherHost
> host_
;
448 scoped_ptr
<media::AudioManager
> audio_manager_
;
449 scoped_ptr
<MediaStreamManagerForTest
> media_stream_manager_
;
450 ContentBrowserClient
* old_browser_client_
;
451 scoped_ptr
<ContentClient
> content_client_
;
452 content::TestBrowserThreadBundle thread_bundle_
;
453 content::TestBrowserContext browser_context_
;
454 media::AudioDeviceNames physical_audio_devices_
;
455 media::VideoCaptureDevice::Names physical_video_devices_
;
457 media::FakeVideoCaptureDeviceFactory
* video_capture_device_factory_
;
460 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithVideoOnly
) {
461 StreamOptions
options(false, true);
464 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
466 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
467 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
470 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioOnly
) {
471 StreamOptions
options(true, false);
474 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
476 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
477 EXPECT_EQ(host_
->video_devices_
.size(), 0u);
480 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithNothing
) {
481 StreamOptions
options(false, false);
483 GenerateStreamAndWaitForFailure(
487 MEDIA_DEVICE_INVALID_STATE
);
490 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioAndVideo
) {
491 StreamOptions
options(true, true);
494 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
496 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
497 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
500 // This test generates two streams with video only using the same render frame
501 // id. The same capture device with the same device and session id is expected
503 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsFromSameRenderId
) {
504 StreamOptions
options(false, true);
506 // Generate first stream.
508 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
510 // Check the latest generated stream.
511 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
512 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
513 const std::string label1
= host_
->label_
;
514 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
515 const int session_id1
= host_
->video_devices_
.front().session_id
;
517 // Generate second stream.
519 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ 1, options
);
521 // Check the latest generated stream.
522 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
523 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
524 const std::string label2
= host_
->label_
;
525 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
526 int session_id2
= host_
->video_devices_
.front().session_id
;
527 EXPECT_EQ(device_id1
, device_id2
);
528 EXPECT_EQ(session_id1
, session_id2
);
529 EXPECT_NE(label1
, label2
);
532 TEST_F(MediaStreamDispatcherHostTest
,
533 GenerateStreamAndOpenDeviceFromSameRenderId
) {
534 StreamOptions
options(false, true);
536 // Generate first stream.
538 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
540 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
541 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
542 const std::string label1
= host_
->label_
;
543 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
544 const int session_id1
= host_
->video_devices_
.front().session_id
;
546 // Generate second stream.
547 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
, device_id1
);
549 const std::string device_id2
= host_
->opened_device_
.device
.id
;
550 const int session_id2
= host_
->opened_device_
.session_id
;
551 const std::string label2
= host_
->label_
;
553 EXPECT_EQ(device_id1
, device_id2
);
554 EXPECT_NE(session_id1
, session_id2
);
555 EXPECT_NE(label1
, label2
);
559 // This test generates two streams with video only using two separate render
560 // frame ids. The same device id but different session ids are expected.
561 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsDifferentRenderId
) {
562 StreamOptions
options(false, true);
564 // Generate first stream.
566 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
568 // Check the latest generated stream.
569 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
570 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
571 const std::string label1
= host_
->label_
;
572 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
573 const int session_id1
= host_
->video_devices_
.front().session_id
;
575 // Generate second stream from another render frame.
577 GenerateStreamAndWaitForResult(kRenderId
+1, kPageRequestId
+ 1, options
);
579 // Check the latest generated stream.
580 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
581 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
582 const std::string label2
= host_
->label_
;
583 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
584 const int session_id2
= host_
->video_devices_
.front().session_id
;
585 EXPECT_EQ(device_id1
, device_id2
);
586 EXPECT_NE(session_id1
, session_id2
);
587 EXPECT_NE(label1
, label2
);
590 // This test request two streams with video only without waiting for the first
591 // stream to be generated before requesting the second.
592 // The same device id and session ids are expected.
593 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithoutWaiting
) {
594 StreamOptions
options(false, true);
596 // Generate first stream.
600 EXPECT_CALL(*host_
.get(),
601 OnStreamGenerated(kRenderId
, kPageRequestId
, 0, 1));
603 // Generate second stream.
604 EXPECT_CALL(*host_
.get(),
605 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
607 base::RunLoop run_loop1
;
608 base::RunLoop run_loop2
;
609 host_
->OnGenerateStream(kRenderId
, kPageRequestId
, options
, origin_
,
610 run_loop1
.QuitClosure());
611 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
612 run_loop2
.QuitClosure());
618 // Test that we can generate streams where a mandatory sourceId is specified in
620 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithMandatorySourceId
) {
621 ASSERT_GE(physical_audio_devices_
.size(), 1u);
622 ASSERT_GE(physical_video_devices_
.size(), 1u);
624 media::AudioDeviceNames::const_iterator audio_it
=
625 physical_audio_devices_
.begin();
626 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
627 std::string source_id
= content::GetHMACForMediaDeviceID(
628 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
630 audio_it
->unique_id
);
631 ASSERT_FALSE(source_id
.empty());
632 StreamOptions
options(true, true);
633 AddSourceIdConstraint(source_id
, &options
.mandatory_audio
);
636 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
637 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
640 media::VideoCaptureDevice::Names::const_iterator video_it
=
641 physical_video_devices_
.begin();
642 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
643 std::string source_id
= content::GetHMACForMediaDeviceID(
644 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
647 ASSERT_FALSE(source_id
.empty());
648 StreamOptions
options(true, true);
649 AddSourceIdConstraint(source_id
, &options
.mandatory_video
);
652 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
653 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
657 // Test that we can generate streams where a optional sourceId is specified in
659 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithOptionalSourceId
) {
660 ASSERT_GE(physical_audio_devices_
.size(), 1u);
661 ASSERT_GE(physical_video_devices_
.size(), 1u);
663 media::AudioDeviceNames::const_iterator audio_it
=
664 physical_audio_devices_
.begin();
665 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
666 std::string source_id
= content::GetHMACForMediaDeviceID(
667 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
669 audio_it
->unique_id
);
670 ASSERT_FALSE(source_id
.empty());
671 StreamOptions
options(true, true);
672 AddSourceIdConstraint(source_id
, &options
.optional_audio
);
675 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
676 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
679 media::VideoCaptureDevice::Names::const_iterator video_it
=
680 physical_video_devices_
.begin();
681 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
682 std::string source_id
= content::GetHMACForMediaDeviceID(
683 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
686 ASSERT_FALSE(source_id
.empty());
687 StreamOptions
options(true, true);
688 AddSourceIdConstraint(source_id
, &options
.optional_video
);
691 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
692 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
696 // Test that generating a stream with an invalid mandatory video source id fail.
697 TEST_F(MediaStreamDispatcherHostTest
,
698 GenerateStreamsWithInvalidMandatoryVideoSourceId
) {
699 StreamOptions
options(true, true);
700 AddSourceIdConstraint("invalid source id", &options
.mandatory_video
);
702 GenerateStreamAndWaitForFailure(
706 MEDIA_DEVICE_NO_HARDWARE
);
709 // Test that generating a stream with an invalid mandatory audio source id fail.
710 TEST_F(MediaStreamDispatcherHostTest
,
711 GenerateStreamsWithInvalidMandatoryAudioSourceId
) {
712 StreamOptions
options(true, true);
713 AddSourceIdConstraint("invalid source id", &options
.mandatory_audio
);
715 GenerateStreamAndWaitForFailure(
719 MEDIA_DEVICE_NO_HARDWARE
);
722 // Test that generating a stream with an invalid optional video source id
724 TEST_F(MediaStreamDispatcherHostTest
,
725 GenerateStreamsWithInvalidOptionalVideoSourceId
) {
726 StreamOptions
options(true, true);
727 AddSourceIdConstraint("invalid source id", &options
.optional_video
);
730 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
733 // Test that generating a stream with an invalid optional audio source id
735 TEST_F(MediaStreamDispatcherHostTest
,
736 GenerateStreamsWithInvalidOptionalAudioSourceId
) {
737 StreamOptions
options(true, true);
738 AddSourceIdConstraint("invalid source id", &options
.optional_audio
);
741 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
744 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsNoAvailableVideoDevice
) {
745 physical_video_devices_
.clear();
746 video_capture_device_factory_
->set_number_of_devices(0);
747 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
748 StreamOptions
options(true, true);
751 GenerateStreamAndWaitForFailure(kRenderId
, kPageRequestId
, options
,
752 MEDIA_DEVICE_NO_HARDWARE
);
755 // Test that if a OnStopStreamDevice message is received for a device that has
756 // been opened in a MediaStream and by pepper, the device is only stopped for
758 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStream
) {
759 StreamOptions
options(false, true);
762 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
764 std::string stream_request_label
= host_
->label_
;
765 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
766 ASSERT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
767 stream_request_label
).size());
769 // Open the same device by Pepper.
770 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
,
771 video_device_info
.device
.id
);
772 std::string open_device_request_label
= host_
->label_
;
774 // Stop the device in the MediaStream.
775 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
777 EXPECT_EQ(0u, media_stream_manager_
->GetDevicesOpenedByRequest(
778 stream_request_label
).size());
779 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
780 open_device_request_label
).size());
783 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStreamAndRestart
) {
784 StreamOptions
options(true, true);
787 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
789 std::string request_label1
= host_
->label_
;
790 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
791 // Expect that 1 audio and 1 video device has been opened.
792 EXPECT_EQ(2u, media_stream_manager_
->GetDevicesOpenedByRequest(
793 request_label1
).size());
795 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
796 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
797 request_label1
).size());
799 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
800 std::string request_label2
= host_
->label_
;
802 StreamDeviceInfoArray request1_devices
=
803 media_stream_manager_
->GetDevicesOpenedByRequest(request_label1
);
804 StreamDeviceInfoArray request2_devices
=
805 media_stream_manager_
->GetDevicesOpenedByRequest(request_label2
);
807 ASSERT_EQ(1u, request1_devices
.size());
808 ASSERT_EQ(2u, request2_devices
.size());
810 // Test that the same audio device has been opened in both streams.
811 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices
[0],
812 request2_devices
[0]) ||
813 StreamDeviceInfo::IsEqual(request1_devices
[0],
814 request2_devices
[1]));
817 TEST_F(MediaStreamDispatcherHostTest
,
818 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream
) {
819 StreamOptions
options(false, true);
822 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
823 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
825 // Generate a second stream.
826 EXPECT_CALL(*host_
.get(),
827 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
829 base::RunLoop run_loop1
;
830 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
831 run_loop1
.QuitClosure());
833 // Stop the video stream device from stream 1 while waiting for the
834 // second stream to be generated.
835 host_
->OnStopStreamDevice(kRenderId
, host_
->video_devices_
[0].device
.id
);
838 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
841 TEST_F(MediaStreamDispatcherHostTest
, CancelPendingStreamsOnChannelClosing
) {
842 StreamOptions
options(false, true);
844 base::RunLoop run_loop
;
846 // Create multiple GenerateStream requests.
848 for (size_t i
= 1; i
<= streams
; ++i
) {
849 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ i
, options
, origin_
,
850 run_loop
.QuitClosure());
853 // Calling OnChannelClosing() to cancel all the pending requests.
854 host_
->OnChannelClosing();
855 run_loop
.RunUntilIdle();
858 TEST_F(MediaStreamDispatcherHostTest
, StopGeneratedStreamsOnChannelClosing
) {
859 StreamOptions
options(false, true);
861 // Create first group of streams.
862 size_t generated_streams
= 3;
863 for (size_t i
= 0; i
< generated_streams
; ++i
) {
865 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ i
, options
);
868 // Calling OnChannelClosing() to cancel all the pending/generated streams.
869 host_
->OnChannelClosing();
870 base::RunLoop().RunUntilIdle();
873 TEST_F(MediaStreamDispatcherHostTest
, CloseFromUI
) {
874 StreamOptions
options(false, true);
876 base::Closure close_callback
;
877 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
878 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
))
879 .WillOnce(SaveArg
<0>(&close_callback
));
880 media_stream_manager_
->UseFakeUI(stream_ui
.PassAs
<FakeMediaStreamUIProxy
>());
882 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
884 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
885 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
887 ASSERT_FALSE(close_callback
.is_null());
888 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
));
889 close_callback
.Run();
890 base::RunLoop().RunUntilIdle();
893 // Test that the dispatcher is notified if a video device that is in use is
895 TEST_F(MediaStreamDispatcherHostTest
, VideoDeviceUnplugged
) {
896 StreamOptions
options(true, true);
898 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
899 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
900 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
902 video_capture_device_factory_
->set_number_of_devices(0);
904 base::RunLoop run_loop
;
905 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
))
906 .WillOnce(testing::InvokeWithoutArgs(&run_loop
, &base::RunLoop::Quit
));
907 media_stream_manager_
->OnDevicesChanged(
908 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE
);
913 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevices
) {
914 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
915 MEDIA_DEVICE_AUDIO_CAPTURE
);
916 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
919 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevices
) {
920 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
921 MEDIA_DEVICE_VIDEO_CAPTURE
);
922 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
925 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevicesNoAccess
) {
926 media_stream_manager_
->set_mic_access(false);
927 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
928 MEDIA_DEVICE_AUDIO_CAPTURE
);
929 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
932 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevicesNoAccess
) {
933 media_stream_manager_
->set_camera_access(false);
934 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
935 MEDIA_DEVICE_VIDEO_CAPTURE
);
936 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
939 }; // namespace content