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/location.h"
12 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "content/browser/browser_thread_impl.h"
16 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
17 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
18 #include "content/browser/renderer_host/media/media_stream_manager.h"
19 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
20 #include "content/browser/renderer_host/media/video_capture_manager.h"
21 #include "content/common/media/media_stream_messages.h"
22 #include "content/common/media/media_stream_options.h"
23 #include "content/public/browser/media_device_id.h"
24 #include "content/public/common/content_switches.h"
25 #include "content/public/test/mock_resource_context.h"
26 #include "content/public/test/test_browser_context.h"
27 #include "content/public/test/test_browser_thread_bundle.h"
28 #include "content/test/test_content_browser_client.h"
29 #include "content/test/test_content_client.h"
30 #include "ipc/ipc_message_macros.h"
31 #include "media/audio/mock_audio_manager.h"
32 #include "media/base/media_switches.h"
33 #include "media/capture/video/fake_video_capture_device_factory.h"
34 #include "net/url_request/url_request_context.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
38 #if defined(OS_CHROMEOS)
39 #include "chromeos/audio/cras_audio_handler.h"
43 using ::testing::DeleteArg
;
44 using ::testing::DoAll
;
45 using ::testing::InSequence
;
46 using ::testing::Return
;
47 using ::testing::SaveArg
;
49 const int kProcessId
= 5;
50 const int kRenderId
= 6;
51 const int kPageRequestId
= 7;
55 class MockMediaStreamDispatcherHost
: public MediaStreamDispatcherHost
,
56 public TestContentBrowserClient
{
58 MockMediaStreamDispatcherHost(
59 const ResourceContext::SaltCallback salt_callback
,
60 const scoped_refptr
<base::SingleThreadTaskRunner
>& task_runner
,
61 MediaStreamManager
* manager
)
62 : MediaStreamDispatcherHost(kProcessId
, salt_callback
, manager
),
63 task_runner_(task_runner
),
66 // A list of mock methods.
67 MOCK_METHOD4(OnStreamGenerated
,
68 void(int routing_id
, int request_id
, int audio_array_size
,
69 int video_array_size
));
70 MOCK_METHOD3(OnStreamGenerationFailed
, void(int routing_id
,
72 MediaStreamRequestResult result
));
73 MOCK_METHOD1(OnDeviceStopped
, void(int routing_id
));
74 MOCK_METHOD2(OnDeviceOpened
, void(int routing_id
, int request_id
));
76 // Accessor to private functions.
77 void OnGenerateStream(int render_frame_id
,
79 const StreamOptions
& components
,
80 const GURL
& security_origin
,
81 const base::Closure
& quit_closure
) {
82 quit_closures_
.push(quit_closure
);
83 MediaStreamDispatcherHost::OnGenerateStream(
84 render_frame_id
, page_request_id
, components
, security_origin
, false);
87 void OnStopStreamDevice(int render_frame_id
,
88 const std::string
& device_id
) {
89 MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id
, device_id
);
92 void OnOpenDevice(int render_frame_id
,
94 const std::string
& device_id
,
96 const GURL
& security_origin
,
97 const base::Closure
& quit_closure
) {
98 quit_closures_
.push(quit_closure
);
99 MediaStreamDispatcherHost::OnOpenDevice(
100 render_frame_id
, page_request_id
, device_id
, type
, security_origin
);
103 void OnEnumerateDevices(int render_frame_id
,
105 MediaStreamType type
,
106 const GURL
& security_origin
,
107 const base::Closure
& quit_closure
) {
108 quit_closures_
.push(quit_closure
);
109 MediaStreamDispatcherHost::OnEnumerateDevices(
110 render_frame_id
, page_request_id
, type
, security_origin
);
114 StreamDeviceInfoArray audio_devices_
;
115 StreamDeviceInfoArray video_devices_
;
116 StreamDeviceInfo opened_device_
;
117 StreamDeviceInfoArray enumerated_devices_
;
120 ~MockMediaStreamDispatcherHost() override
{}
122 // This method is used to dispatch IPC messages to the renderer. We intercept
123 // these messages here and dispatch to our mock methods to verify the
124 // conversation between this object and the renderer.
125 bool Send(IPC::Message
* message
) override
{
127 current_ipc_
= message
;
129 // In this method we dispatch the messages to the according handlers as if
130 // we are the renderer.
132 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost
, *message
)
133 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated
,
134 OnStreamGeneratedInternal
)
135 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed
,
136 OnStreamGenerationFailedInternal
)
137 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped
, OnDeviceStoppedInternal
)
138 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened
, OnDeviceOpenedInternal
)
139 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated
, OnDevicesEnumerated
)
140 IPC_MESSAGE_UNHANDLED(handled
= false)
141 IPC_END_MESSAGE_MAP()
142 EXPECT_TRUE(handled
);
149 // These handler methods do minimal things and delegate to the mock methods.
150 void OnStreamGeneratedInternal(
153 StreamDeviceInfoArray audio_device_list
,
154 StreamDeviceInfoArray video_device_list
) {
155 OnStreamGenerated(current_ipc_
->routing_id(), request_id
,
156 audio_device_list
.size(), video_device_list
.size());
157 // Notify that the event have occurred.
158 base::Closure quit_closure
= quit_closures_
.front();
159 quit_closures_
.pop();
160 task_runner_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
163 audio_devices_
= audio_device_list
;
164 video_devices_
= video_device_list
;
167 void OnStreamGenerationFailedInternal(
169 content::MediaStreamRequestResult result
) {
170 OnStreamGenerationFailed(current_ipc_
->routing_id(), request_id
, result
);
171 if (!quit_closures_
.empty()) {
172 base::Closure quit_closure
= quit_closures_
.front();
173 quit_closures_
.pop();
174 task_runner_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
180 void OnDeviceStoppedInternal(const std::string
& label
,
181 const content::StreamDeviceInfo
& device
) {
182 if (IsVideoMediaType(device
.device
.type
))
183 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, video_devices_
[0]));
184 if (IsAudioInputMediaType(device
.device
.type
))
185 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, audio_devices_
[0]));
187 OnDeviceStopped(current_ipc_
->routing_id());
190 void OnDeviceOpenedInternal(int request_id
,
191 const std::string
& label
,
192 const StreamDeviceInfo
& device
) {
193 base::Closure quit_closure
= quit_closures_
.front();
194 quit_closures_
.pop();
195 task_runner_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
197 opened_device_
= device
;
200 void OnDevicesEnumerated(int request_id
,
201 const StreamDeviceInfoArray
& devices
) {
202 base::Closure quit_closure
= quit_closures_
.front();
203 quit_closures_
.pop();
204 task_runner_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
205 enumerated_devices_
= devices
;
208 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner_
;
209 IPC::Message
* current_ipc_
;
210 std::queue
<base::Closure
> quit_closures_
;
213 class MockMediaStreamUIProxy
: public FakeMediaStreamUIProxy
{
217 void(const base::Closure
& stop
,
218 const MediaStreamUIProxy::WindowIdCallback
& window_id_callback
));
221 class MediaStreamDispatcherHostTest
: public testing::Test
{
223 MediaStreamDispatcherHostTest()
224 : old_browser_client_(NULL
),
225 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
226 origin_("https://test.com") {
227 audio_manager_
.reset(
228 new media::MockAudioManager(base::ThreadTaskRunnerHandle::Get()));
229 // Make sure we use fake devices to avoid long delays.
230 base::CommandLine::ForCurrentProcess()->AppendSwitch(
231 switches::kUseFakeDeviceForMediaStream
);
232 // Create our own MediaStreamManager.
233 media_stream_manager_
.reset(new MediaStreamManager(audio_manager_
.get()));
234 video_capture_device_factory_
=
235 static_cast<media::FakeVideoCaptureDeviceFactory
*>(
236 media_stream_manager_
->video_capture_manager()
237 ->video_capture_device_factory());
238 DCHECK(video_capture_device_factory_
);
240 // Override the Video Capture Thread that MediaStreamManager constructs.
241 media_stream_manager_
->video_capture_manager()->set_device_task_runner(
242 base::ThreadTaskRunnerHandle::Get());
245 MockResourceContext
* mock_resource_context
=
246 static_cast<MockResourceContext
*>(
247 browser_context_
.GetResourceContext());
249 host_
= new MockMediaStreamDispatcherHost(
250 mock_resource_context
->GetMediaDeviceIDSalt(),
251 base::ThreadTaskRunnerHandle::Get(), media_stream_manager_
.get());
253 // Use the fake content client and browser.
254 content_client_
.reset(new TestContentClient());
255 SetContentClient(content_client_
.get());
256 old_browser_client_
= SetBrowserClientForTesting(host_
.get());
258 #if defined(OS_CHROMEOS)
259 chromeos::CrasAudioHandler::InitializeForTesting();
263 ~MediaStreamDispatcherHostTest() override
{
264 #if defined(OS_CHROMEOS)
265 chromeos::CrasAudioHandler::Shutdown();
269 void SetUp() override
{
270 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
271 ASSERT_GT(physical_video_devices_
.size(), 0u);
273 media_stream_manager_
->audio_input_device_manager()->GetFakeDeviceNames(
274 &physical_audio_devices_
);
275 ASSERT_GT(physical_audio_devices_
.size(), 0u);
278 void TearDown() override
{ host_
->OnChannelClosing(); }
281 virtual void SetupFakeUI(bool expect_started
) {
282 stream_ui_
= new MockMediaStreamUIProxy();
283 if (expect_started
) {
284 EXPECT_CALL(*stream_ui_
, OnStarted(_
, _
));
286 media_stream_manager_
->UseFakeUI(
287 scoped_ptr
<FakeMediaStreamUIProxy
>(stream_ui_
));
290 void GenerateStreamAndWaitForResult(int render_frame_id
,
292 const StreamOptions
& options
) {
293 base::RunLoop run_loop
;
294 int expected_audio_array_size
=
295 (options
.audio_requested
&&
296 physical_audio_devices_
.size() > 0) ? 1 : 0;
297 int expected_video_array_size
=
298 (options
.video_requested
&&
299 physical_video_devices_
.size() > 0) ? 1 : 0;
300 EXPECT_CALL(*host_
.get(), OnStreamGenerated(render_frame_id
,
302 expected_audio_array_size
,
303 expected_video_array_size
));
304 host_
->OnGenerateStream(render_frame_id
, page_request_id
, options
, origin_
,
305 run_loop
.QuitClosure());
307 EXPECT_FALSE(DoesContainRawIds(host_
->audio_devices_
));
308 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
309 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->audio_devices_
, origin_
));
310 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
313 void GenerateStreamAndWaitForFailure(
316 const StreamOptions
& options
,
317 MediaStreamRequestResult expected_result
) {
318 base::RunLoop run_loop
;
319 EXPECT_CALL(*host_
.get(),
320 OnStreamGenerationFailed(render_frame_id
,
323 host_
->OnGenerateStream(render_frame_id
, page_request_id
, options
,
324 origin_
, run_loop
.QuitClosure());
328 void OpenVideoDeviceAndWaitForResult(int render_frame_id
,
330 const std::string
& device_id
) {
331 base::RunLoop run_loop
;
332 host_
->OnOpenDevice(render_frame_id
, page_request_id
, device_id
,
333 MEDIA_DEVICE_VIDEO_CAPTURE
, origin_
,
334 run_loop
.QuitClosure());
336 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
337 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
340 void EnumerateDevicesAndWaitForResult(int render_frame_id
,
342 MediaStreamType type
) {
343 base::RunLoop run_loop
;
344 host_
->OnEnumerateDevices(render_frame_id
, page_request_id
, type
, origin_
,
345 run_loop
.QuitClosure());
347 ASSERT_FALSE(host_
->enumerated_devices_
.empty());
348 EXPECT_FALSE(DoesContainRawIds(host_
->enumerated_devices_
));
349 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->enumerated_devices_
, origin_
));
352 bool DoesContainRawIds(const StreamDeviceInfoArray
& devices
) {
353 for (size_t i
= 0; i
< devices
.size(); ++i
) {
354 media::AudioDeviceNames::const_iterator audio_it
=
355 physical_audio_devices_
.begin();
356 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
357 if (audio_it
->unique_id
== devices
[i
].device
.id
)
360 media::VideoCaptureDevice::Names::const_iterator video_it
=
361 physical_video_devices_
.begin();
362 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
363 if (video_it
->id() == devices
[i
].device
.id
)
370 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray
& devices
,
371 const GURL
& origin
) {
372 for (size_t i
= 0; i
< devices
.size(); ++i
) {
373 bool found_match
= false;
374 media::AudioDeviceNames::const_iterator audio_it
=
375 physical_audio_devices_
.begin();
376 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
377 if (content::DoesMediaDeviceIDMatchHMAC(
378 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
380 devices
[i
].device
.id
,
381 audio_it
->unique_id
)) {
382 EXPECT_FALSE(found_match
);
386 media::VideoCaptureDevice::Names::const_iterator video_it
=
387 physical_video_devices_
.begin();
388 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
389 if (content::DoesMediaDeviceIDMatchHMAC(
390 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
392 devices
[i
].device
.id
,
394 EXPECT_FALSE(found_match
);
404 // Returns true if all devices have labels, false otherwise.
405 bool DoesContainLabels(const StreamDeviceInfoArray
& devices
) {
406 for (size_t i
= 0; i
< devices
.size(); ++i
) {
407 if (devices
[i
].device
.name
.empty())
413 // Returns true if no devices have labels, false otherwise.
414 bool DoesNotContainLabels(const StreamDeviceInfoArray
& devices
) {
415 for (size_t i
= 0; i
< devices
.size(); ++i
) {
416 if (!devices
[i
].device
.name
.empty())
422 void AddSourceIdConstraint(const std::string
& source_id
,
423 StreamOptions::Constraints
* constraints
) {
424 constraints
->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId
,
428 scoped_refptr
<MockMediaStreamDispatcherHost
> host_
;
429 scoped_ptr
<media::AudioManager
> audio_manager_
;
430 scoped_ptr
<MediaStreamManager
> media_stream_manager_
;
431 MockMediaStreamUIProxy
* stream_ui_
;
432 ContentBrowserClient
* old_browser_client_
;
433 scoped_ptr
<ContentClient
> content_client_
;
434 content::TestBrowserThreadBundle thread_bundle_
;
435 content::TestBrowserContext browser_context_
;
436 media::AudioDeviceNames physical_audio_devices_
;
437 media::VideoCaptureDevice::Names physical_video_devices_
;
439 media::FakeVideoCaptureDeviceFactory
* video_capture_device_factory_
;
442 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithVideoOnly
) {
443 StreamOptions
options(false, true);
446 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
448 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
449 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
452 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioOnly
) {
453 StreamOptions
options(true, false);
456 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
458 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
459 EXPECT_EQ(host_
->video_devices_
.size(), 0u);
462 // This test simulates a shutdown scenario: we don't setup a fake UI proxy for
463 // MediaStreamManager, so it will create an ordinary one which will not find
464 // a RenderFrameHostDelegate. This normally should only be the case at shutdown.
465 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithNothing
) {
466 StreamOptions
options(false, false);
468 GenerateStreamAndWaitForFailure(
472 MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN
);
475 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioAndVideo
) {
476 StreamOptions
options(true, true);
479 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
481 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
482 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
485 // This test generates two streams with video only using the same render frame
486 // id. The same capture device with the same device and session id is expected
488 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsFromSameRenderId
) {
489 StreamOptions
options(false, true);
491 // Generate first stream.
493 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
495 // Check the latest generated stream.
496 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
497 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
498 const std::string label1
= host_
->label_
;
499 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
500 const int session_id1
= host_
->video_devices_
.front().session_id
;
502 // Generate second stream.
504 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ 1, options
);
506 // Check the latest generated stream.
507 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
508 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
509 const std::string label2
= host_
->label_
;
510 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
511 int session_id2
= host_
->video_devices_
.front().session_id
;
512 EXPECT_EQ(device_id1
, device_id2
);
513 EXPECT_EQ(session_id1
, session_id2
);
514 EXPECT_NE(label1
, label2
);
517 TEST_F(MediaStreamDispatcherHostTest
,
518 GenerateStreamAndOpenDeviceFromSameRenderId
) {
519 StreamOptions
options(false, true);
521 // Generate first stream.
523 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
525 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
526 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
527 const std::string label1
= host_
->label_
;
528 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
529 const int session_id1
= host_
->video_devices_
.front().session_id
;
531 // Generate second stream.
532 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
, device_id1
);
534 const std::string device_id2
= host_
->opened_device_
.device
.id
;
535 const int session_id2
= host_
->opened_device_
.session_id
;
536 const std::string label2
= host_
->label_
;
538 EXPECT_EQ(device_id1
, device_id2
);
539 EXPECT_NE(session_id1
, session_id2
);
540 EXPECT_NE(label1
, label2
);
544 // This test generates two streams with video only using two separate render
545 // frame ids. The same device id but different session ids are expected.
546 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsDifferentRenderId
) {
547 StreamOptions
options(false, true);
549 // Generate first stream.
551 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
553 // Check the latest generated stream.
554 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
555 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
556 const std::string label1
= host_
->label_
;
557 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
558 const int session_id1
= host_
->video_devices_
.front().session_id
;
560 // Generate second stream from another render frame.
562 GenerateStreamAndWaitForResult(kRenderId
+1, kPageRequestId
+ 1, options
);
564 // Check the latest generated stream.
565 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
566 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
567 const std::string label2
= host_
->label_
;
568 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
569 const int session_id2
= host_
->video_devices_
.front().session_id
;
570 EXPECT_EQ(device_id1
, device_id2
);
571 EXPECT_NE(session_id1
, session_id2
);
572 EXPECT_NE(label1
, label2
);
575 // This test request two streams with video only without waiting for the first
576 // stream to be generated before requesting the second.
577 // The same device id and session ids are expected.
578 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithoutWaiting
) {
579 StreamOptions
options(false, true);
581 // Generate first stream.
585 EXPECT_CALL(*host_
.get(),
586 OnStreamGenerated(kRenderId
, kPageRequestId
, 0, 1));
588 // Generate second stream.
589 EXPECT_CALL(*host_
.get(),
590 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
592 base::RunLoop run_loop1
;
593 base::RunLoop run_loop2
;
594 host_
->OnGenerateStream(kRenderId
, kPageRequestId
, options
, origin_
,
595 run_loop1
.QuitClosure());
596 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
597 run_loop2
.QuitClosure());
603 // Test that we can generate streams where a mandatory sourceId is specified in
605 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithMandatorySourceId
) {
606 ASSERT_GE(physical_audio_devices_
.size(), 1u);
607 ASSERT_GE(physical_video_devices_
.size(), 1u);
609 media::AudioDeviceNames::const_iterator audio_it
=
610 physical_audio_devices_
.begin();
611 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
612 std::string source_id
= content::GetHMACForMediaDeviceID(
613 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
615 audio_it
->unique_id
);
616 ASSERT_FALSE(source_id
.empty());
617 StreamOptions
options(true, true);
618 AddSourceIdConstraint(source_id
, &options
.mandatory_audio
);
621 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
622 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
625 media::VideoCaptureDevice::Names::const_iterator video_it
=
626 physical_video_devices_
.begin();
627 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
628 std::string source_id
= content::GetHMACForMediaDeviceID(
629 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
632 ASSERT_FALSE(source_id
.empty());
633 StreamOptions
options(true, true);
634 AddSourceIdConstraint(source_id
, &options
.mandatory_video
);
637 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
638 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
642 // Test that we can generate streams where a optional sourceId is specified in
644 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithOptionalSourceId
) {
645 ASSERT_GE(physical_audio_devices_
.size(), 1u);
646 ASSERT_GE(physical_video_devices_
.size(), 1u);
648 media::AudioDeviceNames::const_iterator audio_it
=
649 physical_audio_devices_
.begin();
650 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
651 std::string source_id
= content::GetHMACForMediaDeviceID(
652 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
654 audio_it
->unique_id
);
655 ASSERT_FALSE(source_id
.empty());
656 StreamOptions
options(true, true);
657 AddSourceIdConstraint(source_id
, &options
.optional_audio
);
660 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
661 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
664 media::VideoCaptureDevice::Names::const_iterator video_it
=
665 physical_video_devices_
.begin();
666 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
667 std::string source_id
= content::GetHMACForMediaDeviceID(
668 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
671 ASSERT_FALSE(source_id
.empty());
672 StreamOptions
options(true, true);
673 AddSourceIdConstraint(source_id
, &options
.optional_video
);
676 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
677 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
681 // Test that generating a stream with an invalid mandatory video source id fail.
682 TEST_F(MediaStreamDispatcherHostTest
,
683 GenerateStreamsWithInvalidMandatoryVideoSourceId
) {
684 StreamOptions
options(true, true);
685 AddSourceIdConstraint("invalid source id", &options
.mandatory_video
);
687 GenerateStreamAndWaitForFailure(
691 MEDIA_DEVICE_NO_HARDWARE
);
694 // Test that generating a stream with an invalid mandatory audio source id fail.
695 TEST_F(MediaStreamDispatcherHostTest
,
696 GenerateStreamsWithInvalidMandatoryAudioSourceId
) {
697 StreamOptions
options(true, true);
698 AddSourceIdConstraint("invalid source id", &options
.mandatory_audio
);
700 GenerateStreamAndWaitForFailure(
704 MEDIA_DEVICE_NO_HARDWARE
);
707 // Test that generating a stream with an invalid optional video source id
709 TEST_F(MediaStreamDispatcherHostTest
,
710 GenerateStreamsWithInvalidOptionalVideoSourceId
) {
711 StreamOptions
options(true, true);
712 AddSourceIdConstraint("invalid source id", &options
.optional_video
);
715 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
718 // Test that generating a stream with an invalid optional audio source id
720 TEST_F(MediaStreamDispatcherHostTest
,
721 GenerateStreamsWithInvalidOptionalAudioSourceId
) {
722 StreamOptions
options(true, true);
723 AddSourceIdConstraint("invalid source id", &options
.optional_audio
);
726 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
729 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsNoAvailableVideoDevice
) {
730 physical_video_devices_
.clear();
731 video_capture_device_factory_
->set_number_of_devices(0);
732 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
733 StreamOptions
options(true, true);
736 GenerateStreamAndWaitForFailure(kRenderId
, kPageRequestId
, options
,
737 MEDIA_DEVICE_NO_HARDWARE
);
740 // Test that if a OnStopStreamDevice message is received for a device that has
741 // been opened in a MediaStream and by pepper, the device is only stopped for
743 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStream
) {
744 StreamOptions
options(false, true);
747 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
749 std::string stream_request_label
= host_
->label_
;
750 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
751 ASSERT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
752 stream_request_label
).size());
754 // Open the same device by Pepper.
755 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
,
756 video_device_info
.device
.id
);
757 std::string open_device_request_label
= host_
->label_
;
759 // Stop the device in the MediaStream.
760 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
762 EXPECT_EQ(0u, media_stream_manager_
->GetDevicesOpenedByRequest(
763 stream_request_label
).size());
764 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
765 open_device_request_label
).size());
768 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStreamAndRestart
) {
769 StreamOptions
options(true, true);
772 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
774 std::string request_label1
= host_
->label_
;
775 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
776 // Expect that 1 audio and 1 video device has been opened.
777 EXPECT_EQ(2u, media_stream_manager_
->GetDevicesOpenedByRequest(
778 request_label1
).size());
780 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
781 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
782 request_label1
).size());
784 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
785 std::string request_label2
= host_
->label_
;
787 StreamDeviceInfoArray request1_devices
=
788 media_stream_manager_
->GetDevicesOpenedByRequest(request_label1
);
789 StreamDeviceInfoArray request2_devices
=
790 media_stream_manager_
->GetDevicesOpenedByRequest(request_label2
);
792 ASSERT_EQ(1u, request1_devices
.size());
793 ASSERT_EQ(2u, request2_devices
.size());
795 // Test that the same audio device has been opened in both streams.
796 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices
[0],
797 request2_devices
[0]) ||
798 StreamDeviceInfo::IsEqual(request1_devices
[0],
799 request2_devices
[1]));
802 TEST_F(MediaStreamDispatcherHostTest
,
803 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream
) {
804 StreamOptions
options(false, true);
807 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
808 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
810 // Generate a second stream.
811 EXPECT_CALL(*host_
.get(),
812 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
814 base::RunLoop run_loop1
;
815 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
816 run_loop1
.QuitClosure());
818 // Stop the video stream device from stream 1 while waiting for the
819 // second stream to be generated.
820 host_
->OnStopStreamDevice(kRenderId
, host_
->video_devices_
[0].device
.id
);
823 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
826 TEST_F(MediaStreamDispatcherHostTest
, CancelPendingStreamsOnChannelClosing
) {
827 StreamOptions
options(false, true);
829 base::RunLoop run_loop
;
831 // Create multiple GenerateStream requests.
833 for (size_t i
= 1; i
<= streams
; ++i
) {
834 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ i
, options
, origin_
,
835 run_loop
.QuitClosure());
838 // Calling OnChannelClosing() to cancel all the pending requests.
839 host_
->OnChannelClosing();
840 run_loop
.RunUntilIdle();
843 TEST_F(MediaStreamDispatcherHostTest
, StopGeneratedStreamsOnChannelClosing
) {
844 StreamOptions
options(false, true);
846 // Create first group of streams.
847 size_t generated_streams
= 3;
848 for (size_t i
= 0; i
< generated_streams
; ++i
) {
850 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ i
, options
);
853 // Calling OnChannelClosing() to cancel all the pending/generated streams.
854 host_
->OnChannelClosing();
855 base::RunLoop().RunUntilIdle();
858 TEST_F(MediaStreamDispatcherHostTest
, CloseFromUI
) {
859 StreamOptions
options(false, true);
861 base::Closure close_callback
;
862 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
863 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
))
864 .WillOnce(SaveArg
<0>(&close_callback
));
865 media_stream_manager_
->UseFakeUI(stream_ui
.Pass());
867 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
869 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
870 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
872 ASSERT_FALSE(close_callback
.is_null());
873 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
));
874 close_callback
.Run();
875 base::RunLoop().RunUntilIdle();
878 // Test that the dispatcher is notified if a video device that is in use is
880 TEST_F(MediaStreamDispatcherHostTest
, VideoDeviceUnplugged
) {
881 StreamOptions
options(true, true);
883 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
884 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
885 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
887 video_capture_device_factory_
->set_number_of_devices(0);
889 base::RunLoop run_loop
;
890 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
))
891 .WillOnce(testing::InvokeWithoutArgs(&run_loop
, &base::RunLoop::Quit
));
892 media_stream_manager_
->OnDevicesChanged(
893 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE
);
898 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevices
) {
900 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
901 MEDIA_DEVICE_AUDIO_CAPTURE
);
902 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
905 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevices
) {
907 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
908 MEDIA_DEVICE_VIDEO_CAPTURE
);
909 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
912 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevicesNoAccess
) {
914 stream_ui_
->SetMicAccess(false);
915 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
916 MEDIA_DEVICE_AUDIO_CAPTURE
);
917 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
920 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevicesNoAccess
) {
922 stream_ui_
->SetCameraAccess(false);
923 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
924 MEDIA_DEVICE_VIDEO_CAPTURE
);
925 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
928 }; // namespace content