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"
36 #if defined(OS_CHROMEOS)
37 #include "chromeos/audio/cras_audio_handler.h"
41 using ::testing::DeleteArg
;
42 using ::testing::DoAll
;
43 using ::testing::InSequence
;
44 using ::testing::Return
;
45 using ::testing::SaveArg
;
47 const int kProcessId
= 5;
48 const int kRenderId
= 6;
49 const int kPageRequestId
= 7;
53 class MockMediaStreamDispatcherHost
: public MediaStreamDispatcherHost
,
54 public TestContentBrowserClient
{
56 MockMediaStreamDispatcherHost(
57 const ResourceContext::SaltCallback salt_callback
,
58 const scoped_refptr
<base::MessageLoopProxy
>& message_loop
,
59 MediaStreamManager
* manager
)
60 : MediaStreamDispatcherHost(kProcessId
, salt_callback
, manager
),
61 message_loop_(message_loop
),
64 // A list of mock methods.
65 MOCK_METHOD4(OnStreamGenerated
,
66 void(int routing_id
, int request_id
, int audio_array_size
,
67 int video_array_size
));
68 MOCK_METHOD3(OnStreamGenerationFailed
, void(int routing_id
,
70 MediaStreamRequestResult result
));
71 MOCK_METHOD1(OnDeviceStopped
, void(int routing_id
));
72 MOCK_METHOD2(OnDeviceOpened
, void(int routing_id
, int request_id
));
74 // Accessor to private functions.
75 void OnGenerateStream(int render_frame_id
,
77 const StreamOptions
& components
,
78 const GURL
& security_origin
,
79 const base::Closure
& quit_closure
) {
80 quit_closures_
.push(quit_closure
);
81 MediaStreamDispatcherHost::OnGenerateStream(
82 render_frame_id
, page_request_id
, components
, security_origin
, false);
85 void OnStopStreamDevice(int render_frame_id
,
86 const std::string
& device_id
) {
87 MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id
, device_id
);
90 void OnOpenDevice(int render_frame_id
,
92 const std::string
& device_id
,
94 const GURL
& security_origin
,
95 const base::Closure
& quit_closure
) {
96 quit_closures_
.push(quit_closure
);
97 MediaStreamDispatcherHost::OnOpenDevice(
98 render_frame_id
, page_request_id
, device_id
, type
, security_origin
);
101 void OnEnumerateDevices(int render_frame_id
,
103 MediaStreamType type
,
104 const GURL
& security_origin
,
105 const base::Closure
& quit_closure
) {
106 quit_closures_
.push(quit_closure
);
107 MediaStreamDispatcherHost::OnEnumerateDevices(
108 render_frame_id
, page_request_id
, type
, security_origin
);
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 base::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 // Override the Video Capture Thread that MediaStreamManager constructs.
239 media_stream_manager_
->video_capture_manager()->set_device_task_runner(
240 base::MessageLoopProxy::current());
243 MockResourceContext
* mock_resource_context
=
244 static_cast<MockResourceContext
*>(
245 browser_context_
.GetResourceContext());
247 host_
= new MockMediaStreamDispatcherHost(
248 mock_resource_context
->GetMediaDeviceIDSalt(),
249 base::MessageLoopProxy::current(),
250 media_stream_manager_
.get());
252 // Use the fake content client and browser.
253 content_client_
.reset(new TestContentClient());
254 SetContentClient(content_client_
.get());
255 old_browser_client_
= SetBrowserClientForTesting(host_
.get());
257 #if defined(OS_CHROMEOS)
258 chromeos::CrasAudioHandler::InitializeForTesting();
262 ~MediaStreamDispatcherHostTest() override
{
263 #if defined(OS_CHROMEOS)
264 chromeos::CrasAudioHandler::Shutdown();
268 void SetUp() override
{
269 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
270 ASSERT_GT(physical_video_devices_
.size(), 0u);
272 media_stream_manager_
->audio_input_device_manager()->GetFakeDeviceNames(
273 &physical_audio_devices_
);
274 ASSERT_GT(physical_audio_devices_
.size(), 0u);
277 void TearDown() override
{ host_
->OnChannelClosing(); }
280 virtual void SetupFakeUI(bool expect_started
) {
281 stream_ui_
= new MockMediaStreamUIProxy();
282 if (expect_started
) {
283 EXPECT_CALL(*stream_ui_
, OnStarted(_
, _
));
285 media_stream_manager_
->UseFakeUI(
286 scoped_ptr
<FakeMediaStreamUIProxy
>(stream_ui_
));
289 void GenerateStreamAndWaitForResult(int render_frame_id
,
291 const StreamOptions
& options
) {
292 base::RunLoop run_loop
;
293 int expected_audio_array_size
=
294 (options
.audio_requested
&&
295 physical_audio_devices_
.size() > 0) ? 1 : 0;
296 int expected_video_array_size
=
297 (options
.video_requested
&&
298 physical_video_devices_
.size() > 0) ? 1 : 0;
299 EXPECT_CALL(*host_
.get(), OnStreamGenerated(render_frame_id
,
301 expected_audio_array_size
,
302 expected_video_array_size
));
303 host_
->OnGenerateStream(render_frame_id
, page_request_id
, options
, origin_
,
304 run_loop
.QuitClosure());
306 EXPECT_FALSE(DoesContainRawIds(host_
->audio_devices_
));
307 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
308 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->audio_devices_
, origin_
));
309 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
312 void GenerateStreamAndWaitForFailure(
315 const StreamOptions
& options
,
316 MediaStreamRequestResult expected_result
) {
317 base::RunLoop run_loop
;
318 EXPECT_CALL(*host_
.get(),
319 OnStreamGenerationFailed(render_frame_id
,
322 host_
->OnGenerateStream(render_frame_id
, page_request_id
, options
,
323 origin_
, run_loop
.QuitClosure());
327 void OpenVideoDeviceAndWaitForResult(int render_frame_id
,
329 const std::string
& device_id
) {
330 base::RunLoop run_loop
;
331 host_
->OnOpenDevice(render_frame_id
, page_request_id
, device_id
,
332 MEDIA_DEVICE_VIDEO_CAPTURE
, origin_
,
333 run_loop
.QuitClosure());
335 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
336 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
339 void EnumerateDevicesAndWaitForResult(int render_frame_id
,
341 MediaStreamType type
) {
342 base::RunLoop run_loop
;
343 host_
->OnEnumerateDevices(render_frame_id
, page_request_id
, type
, origin_
,
344 run_loop
.QuitClosure());
346 ASSERT_FALSE(host_
->enumerated_devices_
.empty());
347 EXPECT_FALSE(DoesContainRawIds(host_
->enumerated_devices_
));
348 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->enumerated_devices_
, origin_
));
351 bool DoesContainRawIds(const StreamDeviceInfoArray
& devices
) {
352 for (size_t i
= 0; i
< devices
.size(); ++i
) {
353 media::AudioDeviceNames::const_iterator audio_it
=
354 physical_audio_devices_
.begin();
355 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
356 if (audio_it
->unique_id
== devices
[i
].device
.id
)
359 media::VideoCaptureDevice::Names::const_iterator video_it
=
360 physical_video_devices_
.begin();
361 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
362 if (video_it
->id() == devices
[i
].device
.id
)
369 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray
& devices
,
370 const GURL
& origin
) {
371 for (size_t i
= 0; i
< devices
.size(); ++i
) {
372 bool found_match
= false;
373 media::AudioDeviceNames::const_iterator audio_it
=
374 physical_audio_devices_
.begin();
375 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
376 if (content::DoesMediaDeviceIDMatchHMAC(
377 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
379 devices
[i
].device
.id
,
380 audio_it
->unique_id
)) {
381 EXPECT_FALSE(found_match
);
385 media::VideoCaptureDevice::Names::const_iterator video_it
=
386 physical_video_devices_
.begin();
387 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
388 if (content::DoesMediaDeviceIDMatchHMAC(
389 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
391 devices
[i
].device
.id
,
393 EXPECT_FALSE(found_match
);
403 // Returns true if all devices have labels, false otherwise.
404 bool DoesContainLabels(const StreamDeviceInfoArray
& devices
) {
405 for (size_t i
= 0; i
< devices
.size(); ++i
) {
406 if (devices
[i
].device
.name
.empty())
412 // Returns true if no devices have labels, false otherwise.
413 bool DoesNotContainLabels(const StreamDeviceInfoArray
& devices
) {
414 for (size_t i
= 0; i
< devices
.size(); ++i
) {
415 if (!devices
[i
].device
.name
.empty())
421 void AddSourceIdConstraint(const std::string
& source_id
,
422 StreamOptions::Constraints
* constraints
) {
423 constraints
->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId
,
427 scoped_refptr
<MockMediaStreamDispatcherHost
> host_
;
428 scoped_ptr
<media::AudioManager
> audio_manager_
;
429 scoped_ptr
<MediaStreamManager
> media_stream_manager_
;
430 MockMediaStreamUIProxy
* stream_ui_
;
431 ContentBrowserClient
* old_browser_client_
;
432 scoped_ptr
<ContentClient
> content_client_
;
433 content::TestBrowserThreadBundle thread_bundle_
;
434 content::TestBrowserContext browser_context_
;
435 media::AudioDeviceNames physical_audio_devices_
;
436 media::VideoCaptureDevice::Names physical_video_devices_
;
438 media::FakeVideoCaptureDeviceFactory
* video_capture_device_factory_
;
441 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithVideoOnly
) {
442 StreamOptions
options(false, true);
445 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
447 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
448 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
451 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioOnly
) {
452 StreamOptions
options(true, false);
455 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
457 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
458 EXPECT_EQ(host_
->video_devices_
.size(), 0u);
461 // This test simulates a shutdown scenario: we don't setup a fake UI proxy for
462 // MediaStreamManager, so it will create an ordinary one which will not find
463 // a RenderFrameHostDelegate. This normally should only be the case at shutdown.
464 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithNothing
) {
465 StreamOptions
options(false, false);
467 GenerateStreamAndWaitForFailure(
471 MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN
);
474 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioAndVideo
) {
475 StreamOptions
options(true, true);
478 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
480 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
481 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
484 // This test generates two streams with video only using the same render frame
485 // id. The same capture device with the same device and session id is expected
487 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsFromSameRenderId
) {
488 StreamOptions
options(false, true);
490 // Generate first stream.
492 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, 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 label1
= host_
->label_
;
498 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
499 const int session_id1
= host_
->video_devices_
.front().session_id
;
501 // Generate second stream.
503 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ 1, options
);
505 // Check the latest generated stream.
506 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
507 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
508 const std::string label2
= host_
->label_
;
509 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
510 int session_id2
= host_
->video_devices_
.front().session_id
;
511 EXPECT_EQ(device_id1
, device_id2
);
512 EXPECT_EQ(session_id1
, session_id2
);
513 EXPECT_NE(label1
, label2
);
516 TEST_F(MediaStreamDispatcherHostTest
,
517 GenerateStreamAndOpenDeviceFromSameRenderId
) {
518 StreamOptions
options(false, true);
520 // Generate first stream.
522 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
524 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
525 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
526 const std::string label1
= host_
->label_
;
527 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
528 const int session_id1
= host_
->video_devices_
.front().session_id
;
530 // Generate second stream.
531 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
, device_id1
);
533 const std::string device_id2
= host_
->opened_device_
.device
.id
;
534 const int session_id2
= host_
->opened_device_
.session_id
;
535 const std::string label2
= host_
->label_
;
537 EXPECT_EQ(device_id1
, device_id2
);
538 EXPECT_NE(session_id1
, session_id2
);
539 EXPECT_NE(label1
, label2
);
543 // This test generates two streams with video only using two separate render
544 // frame ids. The same device id but different session ids are expected.
545 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsDifferentRenderId
) {
546 StreamOptions
options(false, true);
548 // Generate first stream.
550 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, 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 label1
= host_
->label_
;
556 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
557 const int session_id1
= host_
->video_devices_
.front().session_id
;
559 // Generate second stream from another render frame.
561 GenerateStreamAndWaitForResult(kRenderId
+1, kPageRequestId
+ 1, options
);
563 // Check the latest generated stream.
564 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
565 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
566 const std::string label2
= host_
->label_
;
567 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
568 const int session_id2
= host_
->video_devices_
.front().session_id
;
569 EXPECT_EQ(device_id1
, device_id2
);
570 EXPECT_NE(session_id1
, session_id2
);
571 EXPECT_NE(label1
, label2
);
574 // This test request two streams with video only without waiting for the first
575 // stream to be generated before requesting the second.
576 // The same device id and session ids are expected.
577 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithoutWaiting
) {
578 StreamOptions
options(false, true);
580 // Generate first stream.
584 EXPECT_CALL(*host_
.get(),
585 OnStreamGenerated(kRenderId
, kPageRequestId
, 0, 1));
587 // Generate second stream.
588 EXPECT_CALL(*host_
.get(),
589 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
591 base::RunLoop run_loop1
;
592 base::RunLoop run_loop2
;
593 host_
->OnGenerateStream(kRenderId
, kPageRequestId
, options
, origin_
,
594 run_loop1
.QuitClosure());
595 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
596 run_loop2
.QuitClosure());
602 // Test that we can generate streams where a mandatory sourceId is specified in
604 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithMandatorySourceId
) {
605 ASSERT_GE(physical_audio_devices_
.size(), 1u);
606 ASSERT_GE(physical_video_devices_
.size(), 1u);
608 media::AudioDeviceNames::const_iterator audio_it
=
609 physical_audio_devices_
.begin();
610 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
611 std::string source_id
= content::GetHMACForMediaDeviceID(
612 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
614 audio_it
->unique_id
);
615 ASSERT_FALSE(source_id
.empty());
616 StreamOptions
options(true, true);
617 AddSourceIdConstraint(source_id
, &options
.mandatory_audio
);
620 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
621 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
624 media::VideoCaptureDevice::Names::const_iterator video_it
=
625 physical_video_devices_
.begin();
626 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
627 std::string source_id
= content::GetHMACForMediaDeviceID(
628 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
631 ASSERT_FALSE(source_id
.empty());
632 StreamOptions
options(true, true);
633 AddSourceIdConstraint(source_id
, &options
.mandatory_video
);
636 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
637 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
641 // Test that we can generate streams where a optional sourceId is specified in
643 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithOptionalSourceId
) {
644 ASSERT_GE(physical_audio_devices_
.size(), 1u);
645 ASSERT_GE(physical_video_devices_
.size(), 1u);
647 media::AudioDeviceNames::const_iterator audio_it
=
648 physical_audio_devices_
.begin();
649 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
650 std::string source_id
= content::GetHMACForMediaDeviceID(
651 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
653 audio_it
->unique_id
);
654 ASSERT_FALSE(source_id
.empty());
655 StreamOptions
options(true, true);
656 AddSourceIdConstraint(source_id
, &options
.optional_audio
);
659 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
660 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
663 media::VideoCaptureDevice::Names::const_iterator video_it
=
664 physical_video_devices_
.begin();
665 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
666 std::string source_id
= content::GetHMACForMediaDeviceID(
667 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
670 ASSERT_FALSE(source_id
.empty());
671 StreamOptions
options(true, true);
672 AddSourceIdConstraint(source_id
, &options
.optional_video
);
675 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
676 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
680 // Test that generating a stream with an invalid mandatory video source id fail.
681 TEST_F(MediaStreamDispatcherHostTest
,
682 GenerateStreamsWithInvalidMandatoryVideoSourceId
) {
683 StreamOptions
options(true, true);
684 AddSourceIdConstraint("invalid source id", &options
.mandatory_video
);
686 GenerateStreamAndWaitForFailure(
690 MEDIA_DEVICE_NO_HARDWARE
);
693 // Test that generating a stream with an invalid mandatory audio source id fail.
694 TEST_F(MediaStreamDispatcherHostTest
,
695 GenerateStreamsWithInvalidMandatoryAudioSourceId
) {
696 StreamOptions
options(true, true);
697 AddSourceIdConstraint("invalid source id", &options
.mandatory_audio
);
699 GenerateStreamAndWaitForFailure(
703 MEDIA_DEVICE_NO_HARDWARE
);
706 // Test that generating a stream with an invalid optional video source id
708 TEST_F(MediaStreamDispatcherHostTest
,
709 GenerateStreamsWithInvalidOptionalVideoSourceId
) {
710 StreamOptions
options(true, true);
711 AddSourceIdConstraint("invalid source id", &options
.optional_video
);
714 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
717 // Test that generating a stream with an invalid optional audio source id
719 TEST_F(MediaStreamDispatcherHostTest
,
720 GenerateStreamsWithInvalidOptionalAudioSourceId
) {
721 StreamOptions
options(true, true);
722 AddSourceIdConstraint("invalid source id", &options
.optional_audio
);
725 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
728 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsNoAvailableVideoDevice
) {
729 physical_video_devices_
.clear();
730 video_capture_device_factory_
->set_number_of_devices(0);
731 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
732 StreamOptions
options(true, true);
735 GenerateStreamAndWaitForFailure(kRenderId
, kPageRequestId
, options
,
736 MEDIA_DEVICE_NO_HARDWARE
);
739 // Test that if a OnStopStreamDevice message is received for a device that has
740 // been opened in a MediaStream and by pepper, the device is only stopped for
742 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStream
) {
743 StreamOptions
options(false, true);
746 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
748 std::string stream_request_label
= host_
->label_
;
749 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
750 ASSERT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
751 stream_request_label
).size());
753 // Open the same device by Pepper.
754 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
,
755 video_device_info
.device
.id
);
756 std::string open_device_request_label
= host_
->label_
;
758 // Stop the device in the MediaStream.
759 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
761 EXPECT_EQ(0u, media_stream_manager_
->GetDevicesOpenedByRequest(
762 stream_request_label
).size());
763 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
764 open_device_request_label
).size());
767 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStreamAndRestart
) {
768 StreamOptions
options(true, true);
771 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
773 std::string request_label1
= host_
->label_
;
774 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
775 // Expect that 1 audio and 1 video device has been opened.
776 EXPECT_EQ(2u, media_stream_manager_
->GetDevicesOpenedByRequest(
777 request_label1
).size());
779 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
780 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
781 request_label1
).size());
783 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
784 std::string request_label2
= host_
->label_
;
786 StreamDeviceInfoArray request1_devices
=
787 media_stream_manager_
->GetDevicesOpenedByRequest(request_label1
);
788 StreamDeviceInfoArray request2_devices
=
789 media_stream_manager_
->GetDevicesOpenedByRequest(request_label2
);
791 ASSERT_EQ(1u, request1_devices
.size());
792 ASSERT_EQ(2u, request2_devices
.size());
794 // Test that the same audio device has been opened in both streams.
795 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices
[0],
796 request2_devices
[0]) ||
797 StreamDeviceInfo::IsEqual(request1_devices
[0],
798 request2_devices
[1]));
801 TEST_F(MediaStreamDispatcherHostTest
,
802 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream
) {
803 StreamOptions
options(false, true);
806 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
807 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
809 // Generate a second stream.
810 EXPECT_CALL(*host_
.get(),
811 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
813 base::RunLoop run_loop1
;
814 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
815 run_loop1
.QuitClosure());
817 // Stop the video stream device from stream 1 while waiting for the
818 // second stream to be generated.
819 host_
->OnStopStreamDevice(kRenderId
, host_
->video_devices_
[0].device
.id
);
822 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
825 TEST_F(MediaStreamDispatcherHostTest
, CancelPendingStreamsOnChannelClosing
) {
826 StreamOptions
options(false, true);
828 base::RunLoop run_loop
;
830 // Create multiple GenerateStream requests.
832 for (size_t i
= 1; i
<= streams
; ++i
) {
833 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ i
, options
, origin_
,
834 run_loop
.QuitClosure());
837 // Calling OnChannelClosing() to cancel all the pending requests.
838 host_
->OnChannelClosing();
839 run_loop
.RunUntilIdle();
842 TEST_F(MediaStreamDispatcherHostTest
, StopGeneratedStreamsOnChannelClosing
) {
843 StreamOptions
options(false, true);
845 // Create first group of streams.
846 size_t generated_streams
= 3;
847 for (size_t i
= 0; i
< generated_streams
; ++i
) {
849 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ i
, options
);
852 // Calling OnChannelClosing() to cancel all the pending/generated streams.
853 host_
->OnChannelClosing();
854 base::RunLoop().RunUntilIdle();
857 TEST_F(MediaStreamDispatcherHostTest
, CloseFromUI
) {
858 StreamOptions
options(false, true);
860 base::Closure close_callback
;
861 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
862 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
))
863 .WillOnce(SaveArg
<0>(&close_callback
));
864 media_stream_manager_
->UseFakeUI(stream_ui
.Pass());
866 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
868 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
869 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
871 ASSERT_FALSE(close_callback
.is_null());
872 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
));
873 close_callback
.Run();
874 base::RunLoop().RunUntilIdle();
877 // Test that the dispatcher is notified if a video device that is in use is
879 TEST_F(MediaStreamDispatcherHostTest
, VideoDeviceUnplugged
) {
880 StreamOptions
options(true, true);
882 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
883 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
884 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
886 video_capture_device_factory_
->set_number_of_devices(0);
888 base::RunLoop run_loop
;
889 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
))
890 .WillOnce(testing::InvokeWithoutArgs(&run_loop
, &base::RunLoop::Quit
));
891 media_stream_manager_
->OnDevicesChanged(
892 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE
);
897 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevices
) {
899 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
900 MEDIA_DEVICE_AUDIO_CAPTURE
);
901 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
904 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevices
) {
906 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
907 MEDIA_DEVICE_VIDEO_CAPTURE
);
908 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
911 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevicesNoAccess
) {
913 stream_ui_
->SetMicAccess(false);
914 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
915 MEDIA_DEVICE_AUDIO_CAPTURE
);
916 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
919 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevicesNoAccess
) {
921 stream_ui_
->SetCameraAccess(false);
922 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
923 MEDIA_DEVICE_VIDEO_CAPTURE
);
924 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
927 }; // namespace content