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 ResourceContext
* resource_context
)
57 : MediaStreamDispatcherHost(kProcessId
, salt_callback
, manager
,
59 message_loop_(message_loop
),
62 // A list of mock methods.
63 MOCK_METHOD4(OnStreamGenerated
,
64 void(int routing_id
, int request_id
, int audio_array_size
,
65 int video_array_size
));
66 MOCK_METHOD3(OnStreamGenerationFailed
, void(int routing_id
,
68 MediaStreamRequestResult result
));
69 MOCK_METHOD1(OnDeviceStopped
, void(int routing_id
));
70 MOCK_METHOD2(OnDeviceOpened
, void(int routing_id
, int request_id
));
72 // Accessor to private functions.
73 void OnGenerateStream(int render_view_id
,
75 const StreamOptions
& components
,
76 const GURL
& security_origin
,
77 const base::Closure
& quit_closure
) {
78 quit_closures_
.push(quit_closure
);
79 MediaStreamDispatcherHost::OnGenerateStream(
80 render_view_id
, page_request_id
, components
, security_origin
, false);
83 void OnStopStreamDevice(int render_view_id
,
84 const std::string
& device_id
) {
85 MediaStreamDispatcherHost::OnStopStreamDevice(render_view_id
, device_id
);
88 void OnOpenDevice(int render_view_id
,
90 const std::string
& device_id
,
92 const GURL
& security_origin
,
93 const base::Closure
& quit_closure
) {
94 quit_closures_
.push(quit_closure
);
95 MediaStreamDispatcherHost::OnOpenDevice(
96 render_view_id
, page_request_id
, device_id
, type
, security_origin
);
99 void OnEnumerateDevices(int render_view_id
,
101 MediaStreamType type
,
102 const GURL
& security_origin
,
103 bool hide_labels_if_no_access
,
104 const base::Closure
& quit_closure
) {
105 quit_closures_
.push(quit_closure
);
106 MediaStreamDispatcherHost::OnEnumerateDevices(
107 render_view_id
, page_request_id
, type
, security_origin
,
108 hide_labels_if_no_access
);
112 StreamDeviceInfoArray audio_devices_
;
113 StreamDeviceInfoArray video_devices_
;
114 StreamDeviceInfo opened_device_
;
115 StreamDeviceInfoArray enumerated_devices_
;
118 virtual ~MockMediaStreamDispatcherHost() {}
120 // This method is used to dispatch IPC messages to the renderer. We intercept
121 // these messages here and dispatch to our mock methods to verify the
122 // conversation between this object and the renderer.
123 virtual bool Send(IPC::Message
* message
) OVERRIDE
{
125 current_ipc_
= message
;
127 // In this method we dispatch the messages to the according handlers as if
128 // we are the renderer.
130 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost
, *message
)
131 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated
,
132 OnStreamGeneratedInternal
)
133 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed
,
134 OnStreamGenerationFailedInternal
)
135 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped
, OnDeviceStoppedInternal
)
136 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened
, OnDeviceOpenedInternal
)
137 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated
, OnDevicesEnumerated
)
138 IPC_MESSAGE_UNHANDLED(handled
= false)
139 IPC_END_MESSAGE_MAP()
140 EXPECT_TRUE(handled
);
147 // These handler methods do minimal things and delegate to the mock methods.
148 void OnStreamGeneratedInternal(
151 StreamDeviceInfoArray audio_device_list
,
152 StreamDeviceInfoArray video_device_list
) {
153 OnStreamGenerated(current_ipc_
->routing_id(), request_id
,
154 audio_device_list
.size(), video_device_list
.size());
155 // Notify that the event have occurred.
156 base::Closure quit_closure
= quit_closures_
.front();
157 quit_closures_
.pop();
158 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
161 audio_devices_
= audio_device_list
;
162 video_devices_
= video_device_list
;
165 void OnStreamGenerationFailedInternal(
167 content::MediaStreamRequestResult result
) {
168 OnStreamGenerationFailed(current_ipc_
->routing_id(), request_id
, result
);
169 if (!quit_closures_
.empty()) {
170 base::Closure quit_closure
= quit_closures_
.front();
171 quit_closures_
.pop();
172 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
178 void OnDeviceStoppedInternal(const std::string
& label
,
179 const content::StreamDeviceInfo
& device
) {
180 if (IsVideoMediaType(device
.device
.type
))
181 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, video_devices_
[0]));
182 if (IsAudioInputMediaType(device
.device
.type
))
183 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, audio_devices_
[0]));
185 OnDeviceStopped(current_ipc_
->routing_id());
188 void OnDeviceOpenedInternal(int request_id
,
189 const std::string
& label
,
190 const StreamDeviceInfo
& device
) {
191 base::Closure quit_closure
= quit_closures_
.front();
192 quit_closures_
.pop();
193 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
195 opened_device_
= device
;
198 void OnDevicesEnumerated(int request_id
,
199 const StreamDeviceInfoArray
& devices
) {
200 base::Closure quit_closure
= quit_closures_
.front();
201 quit_closures_
.pop();
202 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
203 enumerated_devices_
= devices
;
206 scoped_refptr
<base::MessageLoopProxy
> message_loop_
;
207 IPC::Message
* current_ipc_
;
208 std::queue
<base::Closure
> quit_closures_
;
211 class MockMediaStreamUIProxy
: public FakeMediaStreamUIProxy
{
215 void(const base::Closure
& stop
,
216 const MediaStreamUIProxy::WindowIdCallback
& window_id_callback
));
219 class MediaStreamDispatcherHostTest
: public testing::Test
{
221 MediaStreamDispatcherHostTest()
222 : old_browser_client_(NULL
),
223 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
224 origin_("https://test.com") {
225 audio_manager_
.reset(
226 new media::MockAudioManager(base::MessageLoopProxy::current()));
227 // Make sure we use fake devices to avoid long delays.
228 CommandLine::ForCurrentProcess()->AppendSwitch(
229 switches::kUseFakeDeviceForMediaStream
);
230 // Create our own MediaStreamManager.
231 media_stream_manager_
.reset(new MediaStreamManager(audio_manager_
.get()));
232 video_capture_device_factory_
=
233 static_cast<media::FakeVideoCaptureDeviceFactory
*>(
234 media_stream_manager_
->video_capture_manager()
235 ->video_capture_device_factory());
236 DCHECK(video_capture_device_factory_
);
238 MockResourceContext
* mock_resource_context
=
239 static_cast<MockResourceContext
*>(
240 browser_context_
.GetResourceContext());
241 mock_resource_context
->set_mic_access(true);
242 mock_resource_context
->set_camera_access(true);
244 host_
= new MockMediaStreamDispatcherHost(
245 mock_resource_context
->GetMediaDeviceIDSalt(),
246 base::MessageLoopProxy::current(),
247 media_stream_manager_
.get(),
248 mock_resource_context
);
250 // Use the fake content client and browser.
251 content_client_
.reset(new TestContentClient());
252 SetContentClient(content_client_
.get());
253 old_browser_client_
= SetBrowserClientForTesting(host_
.get());
256 virtual ~MediaStreamDispatcherHostTest() {
259 virtual void SetUp() OVERRIDE
{
260 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
261 ASSERT_GT(physical_video_devices_
.size(), 0u);
263 media_stream_manager_
->audio_input_device_manager()->GetFakeDeviceNames(
264 &physical_audio_devices_
);
265 ASSERT_GT(physical_audio_devices_
.size(), 0u);
268 virtual void TearDown() OVERRIDE
{
269 host_
->OnChannelClosing();
273 virtual void SetupFakeUI(bool expect_started
) {
274 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
275 if (expect_started
) {
276 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
));
278 media_stream_manager_
->UseFakeUI(
279 stream_ui
.PassAs
<FakeMediaStreamUIProxy
>());
282 void GenerateStreamAndWaitForResult(int render_view_id
,
284 const StreamOptions
& options
) {
285 base::RunLoop run_loop
;
286 int expected_audio_array_size
=
287 (options
.audio_requested
&&
288 physical_audio_devices_
.size() > 0) ? 1 : 0;
289 int expected_video_array_size
=
290 (options
.video_requested
&&
291 physical_video_devices_
.size() > 0) ? 1 : 0;
292 EXPECT_CALL(*host_
.get(), OnStreamGenerated(render_view_id
, page_request_id
,
293 expected_audio_array_size
,
294 expected_video_array_size
));
295 host_
->OnGenerateStream(render_view_id
, page_request_id
, options
, origin_
,
296 run_loop
.QuitClosure());
298 EXPECT_FALSE(DoesContainRawIds(host_
->audio_devices_
));
299 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
300 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->audio_devices_
, origin_
));
301 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
304 void GenerateStreamAndWaitForFailure(
307 const StreamOptions
& options
,
308 MediaStreamRequestResult expected_result
) {
309 base::RunLoop run_loop
;
310 EXPECT_CALL(*host_
.get(),
311 OnStreamGenerationFailed(render_view_id
,
314 host_
->OnGenerateStream(render_view_id
, page_request_id
, options
, origin_
,
315 run_loop
.QuitClosure());
319 void OpenVideoDeviceAndWaitForResult(int render_view_id
,
321 const std::string
& device_id
) {
322 base::RunLoop run_loop
;
323 host_
->OnOpenDevice(render_view_id
, page_request_id
, device_id
,
324 MEDIA_DEVICE_VIDEO_CAPTURE
, origin_
,
325 run_loop
.QuitClosure());
327 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
328 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
331 void EnumerateDevicesAndWaitForResult(int render_view_id
,
333 MediaStreamType type
,
334 bool hide_labels_if_no_access
) {
335 base::RunLoop run_loop
;
336 host_
->OnEnumerateDevices(render_view_id
, page_request_id
, type
, origin_
,
337 hide_labels_if_no_access
, run_loop
.QuitClosure());
339 ASSERT_FALSE(host_
->enumerated_devices_
.empty());
340 EXPECT_FALSE(DoesContainRawIds(host_
->enumerated_devices_
));
341 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->enumerated_devices_
, origin_
));
344 bool DoesContainRawIds(const StreamDeviceInfoArray
& devices
) {
345 for (size_t i
= 0; i
< devices
.size(); ++i
) {
346 media::AudioDeviceNames::const_iterator audio_it
=
347 physical_audio_devices_
.begin();
348 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
349 if (audio_it
->unique_id
== devices
[i
].device
.id
)
352 media::VideoCaptureDevice::Names::const_iterator video_it
=
353 physical_video_devices_
.begin();
354 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
355 if (video_it
->id() == devices
[i
].device
.id
)
362 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray
& devices
,
363 const GURL
& origin
) {
364 for (size_t i
= 0; i
< devices
.size(); ++i
) {
365 bool found_match
= false;
366 media::AudioDeviceNames::const_iterator audio_it
=
367 physical_audio_devices_
.begin();
368 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
369 if (content::DoesMediaDeviceIDMatchHMAC(
370 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
372 devices
[i
].device
.id
,
373 audio_it
->unique_id
)) {
374 EXPECT_FALSE(found_match
);
378 media::VideoCaptureDevice::Names::const_iterator video_it
=
379 physical_video_devices_
.begin();
380 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
381 if (content::DoesMediaDeviceIDMatchHMAC(
382 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
384 devices
[i
].device
.id
,
386 EXPECT_FALSE(found_match
);
396 // Returns true if all devices have labels, false otherwise.
397 bool DoesContainLabels(const StreamDeviceInfoArray
& devices
) {
398 for (size_t i
= 0; i
< devices
.size(); ++i
) {
399 if (devices
[i
].device
.name
.empty())
405 // Returns true if no devices have labels, false otherwise.
406 bool DoesNotContainLabels(const StreamDeviceInfoArray
& devices
) {
407 for (size_t i
= 0; i
< devices
.size(); ++i
) {
408 if (!devices
[i
].device
.name
.empty())
414 void AddSourceIdConstraint(const std::string
& source_id
,
415 StreamOptions::Constraints
* constraints
) {
416 constraints
->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId
,
420 scoped_refptr
<MockMediaStreamDispatcherHost
> host_
;
421 scoped_ptr
<media::AudioManager
> audio_manager_
;
422 scoped_ptr
<MediaStreamManager
> media_stream_manager_
;
423 ContentBrowserClient
* old_browser_client_
;
424 scoped_ptr
<ContentClient
> content_client_
;
425 content::TestBrowserThreadBundle thread_bundle_
;
426 content::TestBrowserContext browser_context_
;
427 media::AudioDeviceNames physical_audio_devices_
;
428 media::VideoCaptureDevice::Names physical_video_devices_
;
430 media::FakeVideoCaptureDeviceFactory
* video_capture_device_factory_
;
433 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithVideoOnly
) {
434 StreamOptions
options(false, true);
437 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
439 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
440 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
443 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioOnly
) {
444 StreamOptions
options(true, false);
447 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
449 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
450 EXPECT_EQ(host_
->video_devices_
.size(), 0u);
453 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithNothing
) {
454 StreamOptions
options(false, false);
456 GenerateStreamAndWaitForFailure(
460 MEDIA_DEVICE_INVALID_STATE
);
463 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioAndVideo
) {
464 StreamOptions
options(true, true);
467 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
469 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
470 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
473 // This test generates two streams with video only using the same render view
474 // id. The same capture device with the same device and session id is expected
476 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsFromSameRenderId
) {
477 StreamOptions
options(false, true);
479 // Generate first stream.
481 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
483 // Check the latest generated stream.
484 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
485 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
486 const std::string label1
= host_
->label_
;
487 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
488 const int session_id1
= host_
->video_devices_
.front().session_id
;
490 // Generate second stream.
492 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ 1, options
);
494 // Check the latest generated stream.
495 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
496 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
497 const std::string label2
= host_
->label_
;
498 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
499 int session_id2
= host_
->video_devices_
.front().session_id
;
500 EXPECT_EQ(device_id1
, device_id2
);
501 EXPECT_EQ(session_id1
, session_id2
);
502 EXPECT_NE(label1
, label2
);
505 TEST_F(MediaStreamDispatcherHostTest
,
506 GenerateStreamAndOpenDeviceFromSameRenderId
) {
507 StreamOptions
options(false, true);
509 // Generate first stream.
511 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
513 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
514 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
515 const std::string label1
= host_
->label_
;
516 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
517 const int session_id1
= host_
->video_devices_
.front().session_id
;
519 // Generate second stream.
520 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
, device_id1
);
522 const std::string device_id2
= host_
->opened_device_
.device
.id
;
523 const int session_id2
= host_
->opened_device_
.session_id
;
524 const std::string label2
= host_
->label_
;
526 EXPECT_EQ(device_id1
, device_id2
);
527 EXPECT_NE(session_id1
, session_id2
);
528 EXPECT_NE(label1
, label2
);
532 // This test generates two streams with video only using two separate render
533 // view ids. The same device id but different session ids are expected.
534 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsDifferentRenderId
) {
535 StreamOptions
options(false, true);
537 // Generate first stream.
539 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
541 // Check the latest generated stream.
542 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
543 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
544 const std::string label1
= host_
->label_
;
545 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
546 const int session_id1
= host_
->video_devices_
.front().session_id
;
548 // Generate second stream from another render view.
550 GenerateStreamAndWaitForResult(kRenderId
+1, kPageRequestId
+ 1, options
);
552 // Check the latest generated stream.
553 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
554 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
555 const std::string label2
= host_
->label_
;
556 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
557 const int session_id2
= host_
->video_devices_
.front().session_id
;
558 EXPECT_EQ(device_id1
, device_id2
);
559 EXPECT_NE(session_id1
, session_id2
);
560 EXPECT_NE(label1
, label2
);
563 // This test request two streams with video only without waiting for the first
564 // stream to be generated before requesting the second.
565 // The same device id and session ids are expected.
566 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithoutWaiting
) {
567 StreamOptions
options(false, true);
569 // Generate first stream.
573 EXPECT_CALL(*host_
.get(),
574 OnStreamGenerated(kRenderId
, kPageRequestId
, 0, 1));
576 // Generate second stream.
577 EXPECT_CALL(*host_
.get(),
578 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
580 base::RunLoop run_loop1
;
581 base::RunLoop run_loop2
;
582 host_
->OnGenerateStream(kRenderId
, kPageRequestId
, options
, origin_
,
583 run_loop1
.QuitClosure());
584 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
585 run_loop2
.QuitClosure());
591 // Test that we can generate streams where a mandatory sourceId is specified in
593 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithMandatorySourceId
) {
594 ASSERT_GE(physical_audio_devices_
.size(), 1u);
595 ASSERT_GE(physical_video_devices_
.size(), 1u);
597 media::AudioDeviceNames::const_iterator audio_it
=
598 physical_audio_devices_
.begin();
599 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
600 std::string source_id
= content::GetHMACForMediaDeviceID(
601 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
603 audio_it
->unique_id
);
604 ASSERT_FALSE(source_id
.empty());
605 StreamOptions
options(true, true);
606 AddSourceIdConstraint(source_id
, &options
.mandatory_audio
);
609 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
610 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
613 media::VideoCaptureDevice::Names::const_iterator video_it
=
614 physical_video_devices_
.begin();
615 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
616 std::string source_id
= content::GetHMACForMediaDeviceID(
617 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
620 ASSERT_FALSE(source_id
.empty());
621 StreamOptions
options(true, true);
622 AddSourceIdConstraint(source_id
, &options
.mandatory_video
);
625 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
626 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
630 // Test that we can generate streams where a optional sourceId is specified in
632 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithOptionalSourceId
) {
633 ASSERT_GE(physical_audio_devices_
.size(), 1u);
634 ASSERT_GE(physical_video_devices_
.size(), 1u);
636 media::AudioDeviceNames::const_iterator audio_it
=
637 physical_audio_devices_
.begin();
638 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
639 std::string source_id
= content::GetHMACForMediaDeviceID(
640 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
642 audio_it
->unique_id
);
643 ASSERT_FALSE(source_id
.empty());
644 StreamOptions
options(true, true);
645 AddSourceIdConstraint(source_id
, &options
.optional_audio
);
648 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
649 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
652 media::VideoCaptureDevice::Names::const_iterator video_it
=
653 physical_video_devices_
.begin();
654 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
655 std::string source_id
= content::GetHMACForMediaDeviceID(
656 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
659 ASSERT_FALSE(source_id
.empty());
660 StreamOptions
options(true, true);
661 AddSourceIdConstraint(source_id
, &options
.optional_video
);
664 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
665 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
669 // Test that generating a stream with an invalid mandatory video source id fail.
670 TEST_F(MediaStreamDispatcherHostTest
,
671 GenerateStreamsWithInvalidMandatoryVideoSourceId
) {
672 StreamOptions
options(true, true);
673 AddSourceIdConstraint("invalid source id", &options
.mandatory_video
);
675 GenerateStreamAndWaitForFailure(
679 MEDIA_DEVICE_NO_HARDWARE
);
682 // Test that generating a stream with an invalid mandatory audio source id fail.
683 TEST_F(MediaStreamDispatcherHostTest
,
684 GenerateStreamsWithInvalidMandatoryAudioSourceId
) {
685 StreamOptions
options(true, true);
686 AddSourceIdConstraint("invalid source id", &options
.mandatory_audio
);
688 GenerateStreamAndWaitForFailure(
692 MEDIA_DEVICE_NO_HARDWARE
);
695 // Test that generating a stream with an invalid optional video source id
697 TEST_F(MediaStreamDispatcherHostTest
,
698 GenerateStreamsWithInvalidOptionalVideoSourceId
) {
699 StreamOptions
options(true, true);
700 AddSourceIdConstraint("invalid source id", &options
.optional_video
);
703 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
706 // Test that generating a stream with an invalid optional audio source id
708 TEST_F(MediaStreamDispatcherHostTest
,
709 GenerateStreamsWithInvalidOptionalAudioSourceId
) {
710 StreamOptions
options(true, true);
711 AddSourceIdConstraint("invalid source id", &options
.optional_audio
);
714 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
717 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsNoAvailableVideoDevice
) {
718 physical_video_devices_
.clear();
719 video_capture_device_factory_
->set_number_of_devices(0);
720 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
721 StreamOptions
options(true, true);
724 GenerateStreamAndWaitForFailure(kRenderId
, kPageRequestId
, options
,
725 MEDIA_DEVICE_NO_HARDWARE
);
728 // Test that if a OnStopStreamDevice message is received for a device that has
729 // been opened in a MediaStream and by pepper, the device is only stopped for
731 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStream
) {
732 StreamOptions
options(false, true);
735 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
737 std::string stream_request_label
= host_
->label_
;
738 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
739 ASSERT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
740 stream_request_label
).size());
742 // Open the same device by Pepper.
743 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
,
744 video_device_info
.device
.id
);
745 std::string open_device_request_label
= host_
->label_
;
747 // Stop the device in the MediaStream.
748 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
750 EXPECT_EQ(0u, media_stream_manager_
->GetDevicesOpenedByRequest(
751 stream_request_label
).size());
752 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
753 open_device_request_label
).size());
756 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStreamAndRestart
) {
757 StreamOptions
options(true, true);
760 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
762 std::string request_label1
= host_
->label_
;
763 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
764 // Expect that 1 audio and 1 video device has been opened.
765 EXPECT_EQ(2u, media_stream_manager_
->GetDevicesOpenedByRequest(
766 request_label1
).size());
768 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
769 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
770 request_label1
).size());
772 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
773 std::string request_label2
= host_
->label_
;
775 StreamDeviceInfoArray request1_devices
=
776 media_stream_manager_
->GetDevicesOpenedByRequest(request_label1
);
777 StreamDeviceInfoArray request2_devices
=
778 media_stream_manager_
->GetDevicesOpenedByRequest(request_label2
);
780 ASSERT_EQ(1u, request1_devices
.size());
781 ASSERT_EQ(2u, request2_devices
.size());
783 // Test that the same audio device has been opened in both streams.
784 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices
[0],
785 request2_devices
[0]) ||
786 StreamDeviceInfo::IsEqual(request1_devices
[0],
787 request2_devices
[1]));
790 TEST_F(MediaStreamDispatcherHostTest
,
791 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream
) {
792 StreamOptions
options(false, true);
795 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
796 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
798 // Generate a second stream.
799 EXPECT_CALL(*host_
.get(),
800 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
802 base::RunLoop run_loop1
;
803 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
804 run_loop1
.QuitClosure());
806 // Stop the video stream device from stream 1 while waiting for the
807 // second stream to be generated.
808 host_
->OnStopStreamDevice(kRenderId
, host_
->video_devices_
[0].device
.id
);
811 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
814 TEST_F(MediaStreamDispatcherHostTest
, CancelPendingStreamsOnChannelClosing
) {
815 StreamOptions
options(false, true);
817 base::RunLoop run_loop
;
819 // Create multiple GenerateStream requests.
821 for (size_t i
= 1; i
<= streams
; ++i
) {
822 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ i
, options
, origin_
,
823 run_loop
.QuitClosure());
826 // Calling OnChannelClosing() to cancel all the pending requests.
827 host_
->OnChannelClosing();
828 run_loop
.RunUntilIdle();
831 TEST_F(MediaStreamDispatcherHostTest
, StopGeneratedStreamsOnChannelClosing
) {
832 StreamOptions
options(false, true);
834 // Create first group of streams.
835 size_t generated_streams
= 3;
836 for (size_t i
= 0; i
< generated_streams
; ++i
) {
838 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ i
, options
);
841 // Calling OnChannelClosing() to cancel all the pending/generated streams.
842 host_
->OnChannelClosing();
843 base::RunLoop().RunUntilIdle();
846 TEST_F(MediaStreamDispatcherHostTest
, CloseFromUI
) {
847 StreamOptions
options(false, true);
849 base::Closure close_callback
;
850 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
851 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
))
852 .WillOnce(SaveArg
<0>(&close_callback
));
853 media_stream_manager_
->UseFakeUI(stream_ui
.PassAs
<FakeMediaStreamUIProxy
>());
855 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
857 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
858 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
860 ASSERT_FALSE(close_callback
.is_null());
861 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
));
862 close_callback
.Run();
863 base::RunLoop().RunUntilIdle();
866 // Test that the dispatcher is notified if a video device that is in use is
868 TEST_F(MediaStreamDispatcherHostTest
, VideoDeviceUnplugged
) {
869 StreamOptions
options(true, true);
871 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
872 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
873 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
875 video_capture_device_factory_
->set_number_of_devices(0);
877 base::RunLoop run_loop
;
878 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
))
879 .WillOnce(testing::InvokeWithoutArgs(&run_loop
, &base::RunLoop::Quit
));
880 media_stream_manager_
->OnDevicesChanged(
881 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE
);
886 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevices
) {
887 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
888 MEDIA_DEVICE_AUDIO_CAPTURE
, true);
889 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
892 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevices
) {
893 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
894 MEDIA_DEVICE_VIDEO_CAPTURE
, true);
895 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
898 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevicesNoAccessHideLabels
) {
899 MockResourceContext
* mock_resource_context
=
900 static_cast<MockResourceContext
*>(browser_context_
.GetResourceContext());
901 mock_resource_context
->set_mic_access(false);
902 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
903 MEDIA_DEVICE_AUDIO_CAPTURE
, true);
904 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
907 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevicesNoAccessHideLabels
) {
908 MockResourceContext
* mock_resource_context
=
909 static_cast<MockResourceContext
*>(browser_context_
.GetResourceContext());
910 mock_resource_context
->set_camera_access(false);
911 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
912 MEDIA_DEVICE_VIDEO_CAPTURE
, true);
913 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
916 TEST_F(MediaStreamDispatcherHostTest
,
917 EnumerateAudioDevicesNoAccessNoHideLabels
) {
918 MockResourceContext
* mock_resource_context
=
919 static_cast<MockResourceContext
*>(browser_context_
.GetResourceContext());
920 mock_resource_context
->set_mic_access(false);
921 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
922 MEDIA_DEVICE_AUDIO_CAPTURE
, false);
923 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
926 TEST_F(MediaStreamDispatcherHostTest
,
927 EnumerateVideoDevicesNoAccessNoHideLabels
) {
928 MockResourceContext
* mock_resource_context
=
929 static_cast<MockResourceContext
*>(browser_context_
.GetResourceContext());
930 mock_resource_context
->set_camera_access(false);
931 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
932 MEDIA_DEVICE_VIDEO_CAPTURE
, false);
933 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
936 }; // namespace content