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_frame_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_frame_id
, page_request_id
, components
, security_origin
, false);
83 void OnStopStreamDevice(int render_frame_id
,
84 const std::string
& device_id
) {
85 MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id
, device_id
);
88 void OnOpenDevice(int render_frame_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_frame_id
, page_request_id
, device_id
, type
, security_origin
);
99 void OnEnumerateDevices(int render_frame_id
,
101 MediaStreamType type
,
102 const GURL
& security_origin
,
103 const base::Closure
& quit_closure
) {
104 quit_closures_
.push(quit_closure
);
105 MediaStreamDispatcherHost::OnEnumerateDevices(
106 render_frame_id
, page_request_id
, type
, security_origin
);
110 StreamDeviceInfoArray audio_devices_
;
111 StreamDeviceInfoArray video_devices_
;
112 StreamDeviceInfo opened_device_
;
113 StreamDeviceInfoArray enumerated_devices_
;
116 virtual ~MockMediaStreamDispatcherHost() {}
118 // This method is used to dispatch IPC messages to the renderer. We intercept
119 // these messages here and dispatch to our mock methods to verify the
120 // conversation between this object and the renderer.
121 virtual bool Send(IPC::Message
* message
) OVERRIDE
{
123 current_ipc_
= message
;
125 // In this method we dispatch the messages to the according handlers as if
126 // we are the renderer.
128 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost
, *message
)
129 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated
,
130 OnStreamGeneratedInternal
)
131 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed
,
132 OnStreamGenerationFailedInternal
)
133 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped
, OnDeviceStoppedInternal
)
134 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened
, OnDeviceOpenedInternal
)
135 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated
, OnDevicesEnumerated
)
136 IPC_MESSAGE_UNHANDLED(handled
= false)
137 IPC_END_MESSAGE_MAP()
138 EXPECT_TRUE(handled
);
145 // These handler methods do minimal things and delegate to the mock methods.
146 void OnStreamGeneratedInternal(
149 StreamDeviceInfoArray audio_device_list
,
150 StreamDeviceInfoArray video_device_list
) {
151 OnStreamGenerated(current_ipc_
->routing_id(), request_id
,
152 audio_device_list
.size(), video_device_list
.size());
153 // Notify that the event have occurred.
154 base::Closure quit_closure
= quit_closures_
.front();
155 quit_closures_
.pop();
156 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
159 audio_devices_
= audio_device_list
;
160 video_devices_
= video_device_list
;
163 void OnStreamGenerationFailedInternal(
165 content::MediaStreamRequestResult result
) {
166 OnStreamGenerationFailed(current_ipc_
->routing_id(), request_id
, result
);
167 if (!quit_closures_
.empty()) {
168 base::Closure quit_closure
= quit_closures_
.front();
169 quit_closures_
.pop();
170 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
176 void OnDeviceStoppedInternal(const std::string
& label
,
177 const content::StreamDeviceInfo
& device
) {
178 if (IsVideoMediaType(device
.device
.type
))
179 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, video_devices_
[0]));
180 if (IsAudioInputMediaType(device
.device
.type
))
181 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device
, audio_devices_
[0]));
183 OnDeviceStopped(current_ipc_
->routing_id());
186 void OnDeviceOpenedInternal(int request_id
,
187 const std::string
& label
,
188 const StreamDeviceInfo
& device
) {
189 base::Closure quit_closure
= quit_closures_
.front();
190 quit_closures_
.pop();
191 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
193 opened_device_
= device
;
196 void OnDevicesEnumerated(int request_id
,
197 const StreamDeviceInfoArray
& devices
) {
198 base::Closure quit_closure
= quit_closures_
.front();
199 quit_closures_
.pop();
200 message_loop_
->PostTask(FROM_HERE
, base::ResetAndReturn(&quit_closure
));
201 enumerated_devices_
= devices
;
204 scoped_refptr
<base::MessageLoopProxy
> message_loop_
;
205 IPC::Message
* current_ipc_
;
206 std::queue
<base::Closure
> quit_closures_
;
209 class MockMediaStreamUIProxy
: public FakeMediaStreamUIProxy
{
213 void(const base::Closure
& stop
,
214 const MediaStreamUIProxy::WindowIdCallback
& window_id_callback
));
217 class MediaStreamDispatcherHostTest
: public testing::Test
{
219 MediaStreamDispatcherHostTest()
220 : old_browser_client_(NULL
),
221 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
222 origin_("https://test.com") {
223 audio_manager_
.reset(
224 new media::MockAudioManager(base::MessageLoopProxy::current()));
225 // Make sure we use fake devices to avoid long delays.
226 base::CommandLine::ForCurrentProcess()->AppendSwitch(
227 switches::kUseFakeDeviceForMediaStream
);
228 // Create our own MediaStreamManager.
229 media_stream_manager_
.reset(new MediaStreamManager(audio_manager_
.get()));
230 video_capture_device_factory_
=
231 static_cast<media::FakeVideoCaptureDeviceFactory
*>(
232 media_stream_manager_
->video_capture_manager()
233 ->video_capture_device_factory());
234 DCHECK(video_capture_device_factory_
);
236 MockResourceContext
* mock_resource_context
=
237 static_cast<MockResourceContext
*>(
238 browser_context_
.GetResourceContext());
239 mock_resource_context
->set_mic_access(true);
240 mock_resource_context
->set_camera_access(true);
242 host_
= new MockMediaStreamDispatcherHost(
243 mock_resource_context
->GetMediaDeviceIDSalt(),
244 base::MessageLoopProxy::current(),
245 media_stream_manager_
.get(),
246 mock_resource_context
);
248 // Use the fake content client and browser.
249 content_client_
.reset(new TestContentClient());
250 SetContentClient(content_client_
.get());
251 old_browser_client_
= SetBrowserClientForTesting(host_
.get());
254 virtual ~MediaStreamDispatcherHostTest() {
257 virtual void SetUp() OVERRIDE
{
258 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
259 ASSERT_GT(physical_video_devices_
.size(), 0u);
261 media_stream_manager_
->audio_input_device_manager()->GetFakeDeviceNames(
262 &physical_audio_devices_
);
263 ASSERT_GT(physical_audio_devices_
.size(), 0u);
266 virtual void TearDown() OVERRIDE
{
267 host_
->OnChannelClosing();
271 virtual void SetupFakeUI(bool expect_started
) {
272 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
273 if (expect_started
) {
274 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
));
276 media_stream_manager_
->UseFakeUI(
277 stream_ui
.PassAs
<FakeMediaStreamUIProxy
>());
280 void GenerateStreamAndWaitForResult(int render_frame_id
,
282 const StreamOptions
& options
) {
283 base::RunLoop run_loop
;
284 int expected_audio_array_size
=
285 (options
.audio_requested
&&
286 physical_audio_devices_
.size() > 0) ? 1 : 0;
287 int expected_video_array_size
=
288 (options
.video_requested
&&
289 physical_video_devices_
.size() > 0) ? 1 : 0;
290 EXPECT_CALL(*host_
.get(), OnStreamGenerated(render_frame_id
,
292 expected_audio_array_size
,
293 expected_video_array_size
));
294 host_
->OnGenerateStream(render_frame_id
, page_request_id
, options
, origin_
,
295 run_loop
.QuitClosure());
297 EXPECT_FALSE(DoesContainRawIds(host_
->audio_devices_
));
298 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
299 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->audio_devices_
, origin_
));
300 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
303 void GenerateStreamAndWaitForFailure(
306 const StreamOptions
& options
,
307 MediaStreamRequestResult expected_result
) {
308 base::RunLoop run_loop
;
309 EXPECT_CALL(*host_
.get(),
310 OnStreamGenerationFailed(render_frame_id
,
313 host_
->OnGenerateStream(render_frame_id
, page_request_id
, options
,
314 origin_
, run_loop
.QuitClosure());
318 void OpenVideoDeviceAndWaitForResult(int render_frame_id
,
320 const std::string
& device_id
) {
321 base::RunLoop run_loop
;
322 host_
->OnOpenDevice(render_frame_id
, page_request_id
, device_id
,
323 MEDIA_DEVICE_VIDEO_CAPTURE
, origin_
,
324 run_loop
.QuitClosure());
326 EXPECT_FALSE(DoesContainRawIds(host_
->video_devices_
));
327 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->video_devices_
, origin_
));
330 void EnumerateDevicesAndWaitForResult(int render_frame_id
,
332 MediaStreamType type
) {
333 base::RunLoop run_loop
;
334 host_
->OnEnumerateDevices(render_frame_id
, page_request_id
, type
, origin_
,
335 run_loop
.QuitClosure());
337 ASSERT_FALSE(host_
->enumerated_devices_
.empty());
338 EXPECT_FALSE(DoesContainRawIds(host_
->enumerated_devices_
));
339 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_
->enumerated_devices_
, origin_
));
342 bool DoesContainRawIds(const StreamDeviceInfoArray
& devices
) {
343 for (size_t i
= 0; i
< devices
.size(); ++i
) {
344 media::AudioDeviceNames::const_iterator audio_it
=
345 physical_audio_devices_
.begin();
346 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
347 if (audio_it
->unique_id
== devices
[i
].device
.id
)
350 media::VideoCaptureDevice::Names::const_iterator video_it
=
351 physical_video_devices_
.begin();
352 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
353 if (video_it
->id() == devices
[i
].device
.id
)
360 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray
& devices
,
361 const GURL
& origin
) {
362 for (size_t i
= 0; i
< devices
.size(); ++i
) {
363 bool found_match
= false;
364 media::AudioDeviceNames::const_iterator audio_it
=
365 physical_audio_devices_
.begin();
366 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
367 if (content::DoesMediaDeviceIDMatchHMAC(
368 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
370 devices
[i
].device
.id
,
371 audio_it
->unique_id
)) {
372 EXPECT_FALSE(found_match
);
376 media::VideoCaptureDevice::Names::const_iterator video_it
=
377 physical_video_devices_
.begin();
378 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
379 if (content::DoesMediaDeviceIDMatchHMAC(
380 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
382 devices
[i
].device
.id
,
384 EXPECT_FALSE(found_match
);
394 // Returns true if all devices have labels, false otherwise.
395 bool DoesContainLabels(const StreamDeviceInfoArray
& devices
) {
396 for (size_t i
= 0; i
< devices
.size(); ++i
) {
397 if (devices
[i
].device
.name
.empty())
403 // Returns true if no devices have labels, false otherwise.
404 bool DoesNotContainLabels(const StreamDeviceInfoArray
& devices
) {
405 for (size_t i
= 0; i
< devices
.size(); ++i
) {
406 if (!devices
[i
].device
.name
.empty())
412 void AddSourceIdConstraint(const std::string
& source_id
,
413 StreamOptions::Constraints
* constraints
) {
414 constraints
->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId
,
418 scoped_refptr
<MockMediaStreamDispatcherHost
> host_
;
419 scoped_ptr
<media::AudioManager
> audio_manager_
;
420 scoped_ptr
<MediaStreamManager
> media_stream_manager_
;
421 ContentBrowserClient
* old_browser_client_
;
422 scoped_ptr
<ContentClient
> content_client_
;
423 content::TestBrowserThreadBundle thread_bundle_
;
424 content::TestBrowserContext browser_context_
;
425 media::AudioDeviceNames physical_audio_devices_
;
426 media::VideoCaptureDevice::Names physical_video_devices_
;
428 media::FakeVideoCaptureDeviceFactory
* video_capture_device_factory_
;
431 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithVideoOnly
) {
432 StreamOptions
options(false, true);
435 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
437 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
438 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
441 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioOnly
) {
442 StreamOptions
options(true, false);
445 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
447 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
448 EXPECT_EQ(host_
->video_devices_
.size(), 0u);
451 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithNothing
) {
452 StreamOptions
options(false, false);
454 GenerateStreamAndWaitForFailure(
458 MEDIA_DEVICE_INVALID_STATE
);
461 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamWithAudioAndVideo
) {
462 StreamOptions
options(true, true);
465 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
467 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
468 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
471 // This test generates two streams with video only using the same render frame
472 // id. The same capture device with the same device and session id is expected
474 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsFromSameRenderId
) {
475 StreamOptions
options(false, true);
477 // Generate first stream.
479 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
481 // Check the latest generated stream.
482 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
483 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
484 const std::string label1
= host_
->label_
;
485 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
486 const int session_id1
= host_
->video_devices_
.front().session_id
;
488 // Generate second stream.
490 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ 1, options
);
492 // Check the latest generated stream.
493 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
494 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
495 const std::string label2
= host_
->label_
;
496 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
497 int session_id2
= host_
->video_devices_
.front().session_id
;
498 EXPECT_EQ(device_id1
, device_id2
);
499 EXPECT_EQ(session_id1
, session_id2
);
500 EXPECT_NE(label1
, label2
);
503 TEST_F(MediaStreamDispatcherHostTest
,
504 GenerateStreamAndOpenDeviceFromSameRenderId
) {
505 StreamOptions
options(false, true);
507 // Generate first stream.
509 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
511 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
512 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
513 const std::string label1
= host_
->label_
;
514 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
515 const int session_id1
= host_
->video_devices_
.front().session_id
;
517 // Generate second stream.
518 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
, device_id1
);
520 const std::string device_id2
= host_
->opened_device_
.device
.id
;
521 const int session_id2
= host_
->opened_device_
.session_id
;
522 const std::string label2
= host_
->label_
;
524 EXPECT_EQ(device_id1
, device_id2
);
525 EXPECT_NE(session_id1
, session_id2
);
526 EXPECT_NE(label1
, label2
);
530 // This test generates two streams with video only using two separate render
531 // frame ids. The same device id but different session ids are expected.
532 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsDifferentRenderId
) {
533 StreamOptions
options(false, true);
535 // Generate first stream.
537 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
539 // Check the latest generated stream.
540 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
541 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
542 const std::string label1
= host_
->label_
;
543 const std::string device_id1
= host_
->video_devices_
.front().device
.id
;
544 const int session_id1
= host_
->video_devices_
.front().session_id
;
546 // Generate second stream from another render frame.
548 GenerateStreamAndWaitForResult(kRenderId
+1, kPageRequestId
+ 1, options
);
550 // Check the latest generated stream.
551 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
552 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
553 const std::string label2
= host_
->label_
;
554 const std::string device_id2
= host_
->video_devices_
.front().device
.id
;
555 const int session_id2
= host_
->video_devices_
.front().session_id
;
556 EXPECT_EQ(device_id1
, device_id2
);
557 EXPECT_NE(session_id1
, session_id2
);
558 EXPECT_NE(label1
, label2
);
561 // This test request two streams with video only without waiting for the first
562 // stream to be generated before requesting the second.
563 // The same device id and session ids are expected.
564 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithoutWaiting
) {
565 StreamOptions
options(false, true);
567 // Generate first stream.
571 EXPECT_CALL(*host_
.get(),
572 OnStreamGenerated(kRenderId
, kPageRequestId
, 0, 1));
574 // Generate second stream.
575 EXPECT_CALL(*host_
.get(),
576 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
578 base::RunLoop run_loop1
;
579 base::RunLoop run_loop2
;
580 host_
->OnGenerateStream(kRenderId
, kPageRequestId
, options
, origin_
,
581 run_loop1
.QuitClosure());
582 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
583 run_loop2
.QuitClosure());
589 // Test that we can generate streams where a mandatory sourceId is specified in
591 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithMandatorySourceId
) {
592 ASSERT_GE(physical_audio_devices_
.size(), 1u);
593 ASSERT_GE(physical_video_devices_
.size(), 1u);
595 media::AudioDeviceNames::const_iterator audio_it
=
596 physical_audio_devices_
.begin();
597 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
598 std::string source_id
= content::GetHMACForMediaDeviceID(
599 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
601 audio_it
->unique_id
);
602 ASSERT_FALSE(source_id
.empty());
603 StreamOptions
options(true, true);
604 AddSourceIdConstraint(source_id
, &options
.mandatory_audio
);
607 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
608 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
611 media::VideoCaptureDevice::Names::const_iterator video_it
=
612 physical_video_devices_
.begin();
613 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
614 std::string source_id
= content::GetHMACForMediaDeviceID(
615 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
618 ASSERT_FALSE(source_id
.empty());
619 StreamOptions
options(true, true);
620 AddSourceIdConstraint(source_id
, &options
.mandatory_video
);
623 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
624 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
628 // Test that we can generate streams where a optional sourceId is specified in
630 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsWithOptionalSourceId
) {
631 ASSERT_GE(physical_audio_devices_
.size(), 1u);
632 ASSERT_GE(physical_video_devices_
.size(), 1u);
634 media::AudioDeviceNames::const_iterator audio_it
=
635 physical_audio_devices_
.begin();
636 for (; audio_it
!= physical_audio_devices_
.end(); ++audio_it
) {
637 std::string source_id
= content::GetHMACForMediaDeviceID(
638 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
640 audio_it
->unique_id
);
641 ASSERT_FALSE(source_id
.empty());
642 StreamOptions
options(true, true);
643 AddSourceIdConstraint(source_id
, &options
.optional_audio
);
646 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
647 EXPECT_EQ(host_
->audio_devices_
[0].device
.id
, source_id
);
650 media::VideoCaptureDevice::Names::const_iterator video_it
=
651 physical_video_devices_
.begin();
652 for (; video_it
!= physical_video_devices_
.end(); ++video_it
) {
653 std::string source_id
= content::GetHMACForMediaDeviceID(
654 browser_context_
.GetResourceContext()->GetMediaDeviceIDSalt(),
657 ASSERT_FALSE(source_id
.empty());
658 StreamOptions
options(true, true);
659 AddSourceIdConstraint(source_id
, &options
.optional_video
);
662 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
663 EXPECT_EQ(host_
->video_devices_
[0].device
.id
, source_id
);
667 // Test that generating a stream with an invalid mandatory video source id fail.
668 TEST_F(MediaStreamDispatcherHostTest
,
669 GenerateStreamsWithInvalidMandatoryVideoSourceId
) {
670 StreamOptions
options(true, true);
671 AddSourceIdConstraint("invalid source id", &options
.mandatory_video
);
673 GenerateStreamAndWaitForFailure(
677 MEDIA_DEVICE_NO_HARDWARE
);
680 // Test that generating a stream with an invalid mandatory audio source id fail.
681 TEST_F(MediaStreamDispatcherHostTest
,
682 GenerateStreamsWithInvalidMandatoryAudioSourceId
) {
683 StreamOptions
options(true, true);
684 AddSourceIdConstraint("invalid source id", &options
.mandatory_audio
);
686 GenerateStreamAndWaitForFailure(
690 MEDIA_DEVICE_NO_HARDWARE
);
693 // Test that generating a stream with an invalid optional video source id
695 TEST_F(MediaStreamDispatcherHostTest
,
696 GenerateStreamsWithInvalidOptionalVideoSourceId
) {
697 StreamOptions
options(true, true);
698 AddSourceIdConstraint("invalid source id", &options
.optional_video
);
701 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
704 // Test that generating a stream with an invalid optional audio source id
706 TEST_F(MediaStreamDispatcherHostTest
,
707 GenerateStreamsWithInvalidOptionalAudioSourceId
) {
708 StreamOptions
options(true, true);
709 AddSourceIdConstraint("invalid source id", &options
.optional_audio
);
712 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
715 TEST_F(MediaStreamDispatcherHostTest
, GenerateStreamsNoAvailableVideoDevice
) {
716 physical_video_devices_
.clear();
717 video_capture_device_factory_
->set_number_of_devices(0);
718 video_capture_device_factory_
->GetDeviceNames(&physical_video_devices_
);
719 StreamOptions
options(true, true);
722 GenerateStreamAndWaitForFailure(kRenderId
, kPageRequestId
, options
,
723 MEDIA_DEVICE_NO_HARDWARE
);
726 // Test that if a OnStopStreamDevice message is received for a device that has
727 // been opened in a MediaStream and by pepper, the device is only stopped for
729 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStream
) {
730 StreamOptions
options(false, true);
733 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
735 std::string stream_request_label
= host_
->label_
;
736 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
737 ASSERT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
738 stream_request_label
).size());
740 // Open the same device by Pepper.
741 OpenVideoDeviceAndWaitForResult(kRenderId
, kPageRequestId
,
742 video_device_info
.device
.id
);
743 std::string open_device_request_label
= host_
->label_
;
745 // Stop the device in the MediaStream.
746 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
748 EXPECT_EQ(0u, media_stream_manager_
->GetDevicesOpenedByRequest(
749 stream_request_label
).size());
750 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
751 open_device_request_label
).size());
754 TEST_F(MediaStreamDispatcherHostTest
, StopDeviceInStreamAndRestart
) {
755 StreamOptions
options(true, true);
758 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
760 std::string request_label1
= host_
->label_
;
761 StreamDeviceInfo video_device_info
= host_
->video_devices_
.front();
762 // Expect that 1 audio and 1 video device has been opened.
763 EXPECT_EQ(2u, media_stream_manager_
->GetDevicesOpenedByRequest(
764 request_label1
).size());
766 host_
->OnStopStreamDevice(kRenderId
, video_device_info
.device
.id
);
767 EXPECT_EQ(1u, media_stream_manager_
->GetDevicesOpenedByRequest(
768 request_label1
).size());
770 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
771 std::string request_label2
= host_
->label_
;
773 StreamDeviceInfoArray request1_devices
=
774 media_stream_manager_
->GetDevicesOpenedByRequest(request_label1
);
775 StreamDeviceInfoArray request2_devices
=
776 media_stream_manager_
->GetDevicesOpenedByRequest(request_label2
);
778 ASSERT_EQ(1u, request1_devices
.size());
779 ASSERT_EQ(2u, request2_devices
.size());
781 // Test that the same audio device has been opened in both streams.
782 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices
[0],
783 request2_devices
[0]) ||
784 StreamDeviceInfo::IsEqual(request1_devices
[0],
785 request2_devices
[1]));
788 TEST_F(MediaStreamDispatcherHostTest
,
789 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream
) {
790 StreamOptions
options(false, true);
793 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
794 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
796 // Generate a second stream.
797 EXPECT_CALL(*host_
.get(),
798 OnStreamGenerated(kRenderId
, kPageRequestId
+ 1, 0, 1));
800 base::RunLoop run_loop1
;
801 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ 1, options
, origin_
,
802 run_loop1
.QuitClosure());
804 // Stop the video stream device from stream 1 while waiting for the
805 // second stream to be generated.
806 host_
->OnStopStreamDevice(kRenderId
, host_
->video_devices_
[0].device
.id
);
809 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
812 TEST_F(MediaStreamDispatcherHostTest
, CancelPendingStreamsOnChannelClosing
) {
813 StreamOptions
options(false, true);
815 base::RunLoop run_loop
;
817 // Create multiple GenerateStream requests.
819 for (size_t i
= 1; i
<= streams
; ++i
) {
820 host_
->OnGenerateStream(kRenderId
, kPageRequestId
+ i
, options
, origin_
,
821 run_loop
.QuitClosure());
824 // Calling OnChannelClosing() to cancel all the pending requests.
825 host_
->OnChannelClosing();
826 run_loop
.RunUntilIdle();
829 TEST_F(MediaStreamDispatcherHostTest
, StopGeneratedStreamsOnChannelClosing
) {
830 StreamOptions
options(false, true);
832 // Create first group of streams.
833 size_t generated_streams
= 3;
834 for (size_t i
= 0; i
< generated_streams
; ++i
) {
836 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
+ i
, options
);
839 // Calling OnChannelClosing() to cancel all the pending/generated streams.
840 host_
->OnChannelClosing();
841 base::RunLoop().RunUntilIdle();
844 TEST_F(MediaStreamDispatcherHostTest
, CloseFromUI
) {
845 StreamOptions
options(false, true);
847 base::Closure close_callback
;
848 scoped_ptr
<MockMediaStreamUIProxy
> stream_ui(new MockMediaStreamUIProxy());
849 EXPECT_CALL(*stream_ui
, OnStarted(_
, _
))
850 .WillOnce(SaveArg
<0>(&close_callback
));
851 media_stream_manager_
->UseFakeUI(stream_ui
.PassAs
<FakeMediaStreamUIProxy
>());
853 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
855 EXPECT_EQ(host_
->audio_devices_
.size(), 0u);
856 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
858 ASSERT_FALSE(close_callback
.is_null());
859 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
));
860 close_callback
.Run();
861 base::RunLoop().RunUntilIdle();
864 // Test that the dispatcher is notified if a video device that is in use is
866 TEST_F(MediaStreamDispatcherHostTest
, VideoDeviceUnplugged
) {
867 StreamOptions
options(true, true);
869 GenerateStreamAndWaitForResult(kRenderId
, kPageRequestId
, options
);
870 EXPECT_EQ(host_
->audio_devices_
.size(), 1u);
871 EXPECT_EQ(host_
->video_devices_
.size(), 1u);
873 video_capture_device_factory_
->set_number_of_devices(0);
875 base::RunLoop run_loop
;
876 EXPECT_CALL(*host_
.get(), OnDeviceStopped(kRenderId
))
877 .WillOnce(testing::InvokeWithoutArgs(&run_loop
, &base::RunLoop::Quit
));
878 media_stream_manager_
->OnDevicesChanged(
879 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE
);
884 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevices
) {
885 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
886 MEDIA_DEVICE_AUDIO_CAPTURE
);
887 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
890 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevices
) {
891 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
892 MEDIA_DEVICE_VIDEO_CAPTURE
);
893 EXPECT_TRUE(DoesContainLabels(host_
->enumerated_devices_
));
896 TEST_F(MediaStreamDispatcherHostTest
, EnumerateAudioDevicesNoAccess
) {
897 MockResourceContext
* mock_resource_context
=
898 static_cast<MockResourceContext
*>(browser_context_
.GetResourceContext());
899 mock_resource_context
->set_mic_access(false);
900 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
901 MEDIA_DEVICE_AUDIO_CAPTURE
);
902 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
905 TEST_F(MediaStreamDispatcherHostTest
, EnumerateVideoDevicesNoAccess
) {
906 MockResourceContext
* mock_resource_context
=
907 static_cast<MockResourceContext
*>(browser_context_
.GetResourceContext());
908 mock_resource_context
->set_camera_access(false);
909 EnumerateDevicesAndWaitForResult(kRenderId
, kPageRequestId
,
910 MEDIA_DEVICE_VIDEO_CAPTURE
);
911 EXPECT_TRUE(DoesNotContainLabels(host_
->enumerated_devices_
));
914 }; // namespace content