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/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "content/browser/browser_thread_impl.h"
13 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
14 #include "content/browser/renderer_host/media/media_stream_manager.h"
15 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
16 #include "content/common/media/media_stream_messages.h"
17 #include "content/common/media/media_stream_options.h"
18 #include "content/public/browser/media_device_id.h"
19 #include "content/public/test/mock_resource_context.h"
20 #include "content/public/test/test_browser_context.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "content/test/test_content_browser_client.h"
23 #include "content/test/test_content_client.h"
24 #include "ipc/ipc_message_macros.h"
25 #include "media/audio/mock_audio_manager.h"
26 #include "media/video/capture/fake_video_capture_device.h"
27 #include "net/url_request/url_request_context.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
32 using ::testing::DeleteArg;
33 using ::testing::DoAll;
34 using ::testing::Return;
35 using ::testing::SaveArg;
37 const int kProcessId = 5;
38 const int kRenderId = 6;
39 const int kPageRequestId = 7;
43 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
44 public TestContentBrowserClient {
46 MockMediaStreamDispatcherHost(
47 const ResourceContext::SaltCallback salt_callback,
48 const scoped_refptr<base::MessageLoopProxy>& message_loop,
49 MediaStreamManager* manager)
50 : MediaStreamDispatcherHost(kProcessId, salt_callback, manager),
51 message_loop_(message_loop) {}
53 // A list of mock methods.
54 MOCK_METHOD4(OnStreamGenerated,
55 void(int routing_id, int request_id, int audio_array_size,
56 int video_array_size));
57 MOCK_METHOD2(OnStreamGenerationFailed, void(int routing_id, int request_id));
58 MOCK_METHOD1(OnDeviceStopped, void(int routing_id));
59 MOCK_METHOD2(OnDeviceOpened, void(int routing_id, int request_id));
61 // Accessor to private functions.
62 void OnGenerateStream(int render_view_id,
64 const StreamOptions& components,
65 const GURL& security_origin,
66 const base::Closure& quit_closure) {
67 quit_closures_.push(quit_closure);
68 MediaStreamDispatcherHost::OnGenerateStream(
69 render_view_id, page_request_id, components, security_origin);
72 void OnStopStreamDevice(int render_view_id,
73 const std::string& device_id) {
74 MediaStreamDispatcherHost::OnStopStreamDevice(render_view_id, device_id);
77 void OnOpenDevice(int render_view_id,
79 const std::string& device_id,
81 const GURL& security_origin,
82 const base::Closure& quit_closure) {
83 quit_closures_.push(quit_closure);
84 MediaStreamDispatcherHost::OnOpenDevice(
85 render_view_id, page_request_id, device_id, type, security_origin);
88 void OnEnumerateDevices(int render_view_id,
91 const GURL& security_origin,
92 const base::Closure& quit_closure) {
93 quit_closures_.push(quit_closure);
94 MediaStreamDispatcherHost::OnEnumerateDevices(
95 render_view_id, page_request_id, type, security_origin);
99 StreamDeviceInfoArray audio_devices_;
100 StreamDeviceInfoArray video_devices_;
101 StreamDeviceInfo opened_device_;
102 StreamDeviceInfoArray enumerated_devices_;
105 virtual ~MockMediaStreamDispatcherHost() {}
107 // This method is used to dispatch IPC messages to the renderer. We intercept
108 // these messages here and dispatch to our mock methods to verify the
109 // conversation between this object and the renderer.
110 virtual bool Send(IPC::Message* message) OVERRIDE {
113 // In this method we dispatch the messages to the according handlers as if
114 // we are the renderer.
116 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message)
117 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated, OnStreamGenerated)
118 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed,
119 OnStreamGenerationFailed)
120 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped, OnDeviceStopped)
121 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened, OnDeviceOpened)
122 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated,
124 IPC_MESSAGE_UNHANDLED(handled = false)
125 IPC_END_MESSAGE_MAP()
126 EXPECT_TRUE(handled);
132 // These handler methods do minimal things and delegate to the mock methods.
133 void OnStreamGenerated(
134 const IPC::Message& msg,
137 StreamDeviceInfoArray audio_device_list,
138 StreamDeviceInfoArray video_device_list) {
139 OnStreamGenerated(msg.routing_id(), request_id, audio_device_list.size(),
140 video_device_list.size());
141 // Notify that the event have occurred.
142 base::Closure quit_closure = quit_closures_.front();
143 quit_closures_.pop();
144 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
147 audio_devices_ = audio_device_list;
148 video_devices_ = video_device_list;
151 void OnStreamGenerationFailed(const IPC::Message& msg, int request_id) {
152 OnStreamGenerationFailed(msg.routing_id(), request_id);
153 if (!quit_closures_.empty()) {
154 base::Closure quit_closure = quit_closures_.front();
155 quit_closures_.pop();
156 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
162 void OnDeviceStopped(const IPC::Message& msg,
163 const std::string& label,
164 const content::StreamDeviceInfo& device) {
165 if (IsVideoMediaType(device.device.type))
166 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, video_devices_[0]));
167 if (IsAudioMediaType(device.device.type))
168 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, audio_devices_[0]));
170 OnDeviceStopped(msg.routing_id());
173 void OnDeviceOpened(const IPC::Message& msg,
175 const std::string& label,
176 const StreamDeviceInfo& device) {
177 base::Closure quit_closure = quit_closures_.front();
178 quit_closures_.pop();
179 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
181 opened_device_ = device;
184 void OnDevicesEnumerated(const IPC::Message& msg,
186 const StreamDeviceInfoArray& devices) {
187 base::Closure quit_closure = quit_closures_.front();
188 quit_closures_.pop();
189 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
190 enumerated_devices_ = devices;
193 scoped_refptr<base::MessageLoopProxy> message_loop_;
195 std::queue<base::Closure> quit_closures_;
198 class MockMediaStreamUIProxy : public FakeMediaStreamUIProxy {
200 MOCK_METHOD1(OnStarted, void(const base::Closure& stop));
203 class MediaStreamDispatcherHostTest : public testing::Test {
205 MediaStreamDispatcherHostTest()
206 : old_browser_client_(NULL),
207 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
208 origin_("https://test.com") {
209 audio_manager_.reset(
210 new media::MockAudioManager(base::MessageLoopProxy::current()));
211 // Create our own MediaStreamManager.
212 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
213 // Make sure we use fake devices to avoid long delays.
214 media_stream_manager_->UseFakeDevice();
216 host_ = new MockMediaStreamDispatcherHost(
217 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
218 base::MessageLoopProxy::current(),
219 media_stream_manager_.get());
221 // Use the fake content client and browser.
222 content_client_.reset(new TestContentClient());
223 SetContentClient(content_client_.get());
224 old_browser_client_ = SetBrowserClientForTesting(host_.get());
227 virtual ~MediaStreamDispatcherHostTest() {
230 virtual void SetUp() OVERRIDE {
231 media::FakeVideoCaptureDevice::GetDeviceNames(&physical_video_devices_);
232 ASSERT_GT(physical_video_devices_.size(), 0u);
234 audio_manager_->GetAudioInputDeviceNames(&physical_audio_devices_);
235 ASSERT_GT(physical_audio_devices_.size(), 0u);
238 virtual void TearDown() OVERRIDE {
239 host_->OnChannelClosing();
243 virtual void SetupFakeUI(bool expect_started) {
244 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
245 if (expect_started) {
246 EXPECT_CALL(*stream_ui, OnStarted(_));
248 media_stream_manager_->UseFakeUI(
249 stream_ui.PassAs<FakeMediaStreamUIProxy>());
252 void GenerateStreamAndWaitForResult(int render_view_id,
254 const StreamOptions& options) {
255 base::RunLoop run_loop;
256 int expected_audio_array_size =
257 (options.audio_requested &&
258 physical_audio_devices_.size() > 0) ? 1 : 0;
259 int expected_video_array_size =
260 (options.video_requested &&
261 physical_video_devices_.size() > 0) ? 1 : 0;
262 EXPECT_CALL(*host_.get(), OnStreamGenerated(render_view_id, page_request_id,
263 expected_audio_array_size,
264 expected_video_array_size));
265 host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
266 run_loop.QuitClosure());
268 EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
269 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
270 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
271 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
274 void GenerateStreamAndWaitForFailure(int render_view_id,
276 const StreamOptions& options) {
277 base::RunLoop run_loop;
278 EXPECT_CALL(*host_.get(),
279 OnStreamGenerationFailed(render_view_id, page_request_id));
280 host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
281 run_loop.QuitClosure());
285 void OpenVideoDeviceAndWaitForResult(int render_view_id,
287 const std::string& device_id) {
288 base::RunLoop run_loop;
289 host_->OnOpenDevice(render_view_id, page_request_id, device_id,
290 MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
291 run_loop.QuitClosure());
293 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
294 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
297 void EnumerateDevicesAndWaitForResult(int render_view_id,
299 MediaStreamType type) {
300 base::RunLoop run_loop;
301 host_->OnEnumerateDevices(render_view_id, page_request_id, type, origin_,
302 run_loop.QuitClosure());
304 ASSERT_FALSE(host_->enumerated_devices_.empty());
305 EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
306 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
309 bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
310 for (size_t i = 0; i < devices.size(); ++i) {
311 media::AudioDeviceNames::const_iterator audio_it =
312 physical_audio_devices_.begin();
313 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
314 if (audio_it->unique_id == devices[i].device.id)
317 media::VideoCaptureDevice::Names::const_iterator video_it =
318 physical_video_devices_.begin();
319 for (; video_it != physical_video_devices_.end(); ++video_it) {
320 if (video_it->id() == devices[i].device.id)
327 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
328 const GURL& origin) {
329 for (size_t i = 0; i < devices.size(); ++i) {
330 bool found_match = false;
331 media::AudioDeviceNames::const_iterator audio_it =
332 physical_audio_devices_.begin();
333 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
334 if (content::DoesMediaDeviceIDMatchHMAC(
335 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
337 devices[i].device.id,
338 audio_it->unique_id)) {
339 EXPECT_FALSE(found_match);
343 media::VideoCaptureDevice::Names::const_iterator video_it =
344 physical_video_devices_.begin();
345 for (; video_it != physical_video_devices_.end(); ++video_it) {
346 if (content::DoesMediaDeviceIDMatchHMAC(
347 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
349 devices[i].device.id,
351 EXPECT_FALSE(found_match);
361 void AddSourceIdConstraint(const std::string& source_id,
362 StreamOptions::Constraints* constraints) {
363 constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
367 scoped_refptr<MockMediaStreamDispatcherHost> host_;
368 scoped_ptr<media::AudioManager> audio_manager_;
369 scoped_ptr<MediaStreamManager> media_stream_manager_;
370 ContentBrowserClient* old_browser_client_;
371 scoped_ptr<ContentClient> content_client_;
372 content::TestBrowserThreadBundle thread_bundle_;
373 content::TestBrowserContext browser_context_;
374 media::AudioDeviceNames physical_audio_devices_;
375 media::VideoCaptureDevice::Names physical_video_devices_;
379 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
380 StreamOptions options(false, true);
383 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
385 EXPECT_EQ(host_->audio_devices_.size(), 0u);
386 EXPECT_EQ(host_->video_devices_.size(), 1u);
389 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
390 StreamOptions options(true, false);
393 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
395 EXPECT_EQ(host_->audio_devices_.size(), 1u);
396 EXPECT_EQ(host_->video_devices_.size(), 0u);
399 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
400 StreamOptions options(false, false);
402 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options);
405 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
406 StreamOptions options(true, true);
409 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
411 EXPECT_EQ(host_->audio_devices_.size(), 1u);
412 EXPECT_EQ(host_->video_devices_.size(), 1u);
415 // This test generates two streams with video only using the same render view
416 // id. The same capture device with the same device and session id is expected
418 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
419 StreamOptions options(false, true);
421 // Generate first stream.
423 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
425 // Check the latest generated stream.
426 EXPECT_EQ(host_->audio_devices_.size(), 0u);
427 EXPECT_EQ(host_->video_devices_.size(), 1u);
428 const std::string label1 = host_->label_;
429 const std::string device_id1 = host_->video_devices_.front().device.id;
430 const int session_id1 = host_->video_devices_.front().session_id;
432 // Generate second stream.
434 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
436 // Check the latest generated stream.
437 EXPECT_EQ(host_->audio_devices_.size(), 0u);
438 EXPECT_EQ(host_->video_devices_.size(), 1u);
439 const std::string label2 = host_->label_;
440 const std::string device_id2 = host_->video_devices_.front().device.id;
441 int session_id2 = host_->video_devices_.front().session_id;
442 EXPECT_EQ(device_id1, device_id2);
443 EXPECT_EQ(session_id1, session_id2);
444 EXPECT_NE(label1, label2);
447 TEST_F(MediaStreamDispatcherHostTest,
448 GenerateStreamAndOpenDeviceFromSameRenderId) {
449 StreamOptions options(false, true);
451 // Generate first stream.
453 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
455 EXPECT_EQ(host_->audio_devices_.size(), 0u);
456 EXPECT_EQ(host_->video_devices_.size(), 1u);
457 const std::string label1 = host_->label_;
458 const std::string device_id1 = host_->video_devices_.front().device.id;
459 const int session_id1 = host_->video_devices_.front().session_id;
461 // Generate second stream.
462 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
464 const std::string device_id2 = host_->opened_device_.device.id;
465 const int session_id2 = host_->opened_device_.session_id;
466 const std::string label2 = host_->label_;
468 EXPECT_EQ(device_id1, device_id2);
469 EXPECT_NE(session_id1, session_id2);
470 EXPECT_NE(label1, label2);
474 // This test generates two streams with video only using two separate render
475 // view ids. The same device id but different session ids are expected.
476 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
477 StreamOptions options(false, true);
479 // Generate first stream.
481 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
483 // Check the latest generated stream.
484 EXPECT_EQ(host_->audio_devices_.size(), 0u);
485 EXPECT_EQ(host_->video_devices_.size(), 1u);
486 const std::string label1 = host_->label_;
487 const std::string device_id1 = host_->video_devices_.front().device.id;
488 const int session_id1 = host_->video_devices_.front().session_id;
490 // Generate second stream from another render view.
492 GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
494 // Check the latest generated stream.
495 EXPECT_EQ(host_->audio_devices_.size(), 0u);
496 EXPECT_EQ(host_->video_devices_.size(), 1u);
497 const std::string label2 = host_->label_;
498 const std::string device_id2 = host_->video_devices_.front().device.id;
499 const int session_id2 = host_->video_devices_.front().session_id;
500 EXPECT_EQ(device_id1, device_id2);
501 EXPECT_NE(session_id1, session_id2);
502 EXPECT_NE(label1, label2);
505 // This test request two streams with video only without waiting for the first
506 // stream to be generated before requesting the second.
507 // The same device id and session ids are expected.
508 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
509 StreamOptions options(false, true);
511 // Generate first stream.
513 EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
515 // Generate second stream.
516 EXPECT_CALL(*host_.get(),
517 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
519 base::RunLoop run_loop1;
520 base::RunLoop run_loop2;
521 host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
522 run_loop1.QuitClosure());
523 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
524 run_loop2.QuitClosure());
530 // Test that we can generate streams where a mandatory sourceId is specified in
532 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
533 ASSERT_GE(physical_audio_devices_.size(), 1u);
534 ASSERT_GE(physical_video_devices_.size(), 1u);
536 media::AudioDeviceNames::const_iterator audio_it =
537 physical_audio_devices_.begin();
538 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
539 std::string source_id = content::GetHMACForMediaDeviceID(
540 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
542 audio_it->unique_id);
543 ASSERT_FALSE(source_id.empty());
544 StreamOptions options(true, true);
545 AddSourceIdConstraint(source_id, &options.mandatory_audio);
548 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
549 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
552 media::VideoCaptureDevice::Names::const_iterator video_it =
553 physical_video_devices_.begin();
554 for (; video_it != physical_video_devices_.end(); ++video_it) {
555 std::string source_id = content::GetHMACForMediaDeviceID(
556 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
559 ASSERT_FALSE(source_id.empty());
560 StreamOptions options(true, true);
561 AddSourceIdConstraint(source_id, &options.mandatory_video);
564 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
565 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
569 // Test that we can generate streams where a optional sourceId is specified in
571 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
572 ASSERT_GE(physical_audio_devices_.size(), 1u);
573 ASSERT_GE(physical_video_devices_.size(), 1u);
575 media::AudioDeviceNames::const_iterator audio_it =
576 physical_audio_devices_.begin();
577 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
578 std::string source_id = content::GetHMACForMediaDeviceID(
579 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
581 audio_it->unique_id);
582 ASSERT_FALSE(source_id.empty());
583 StreamOptions options(true, true);
584 AddSourceIdConstraint(source_id, &options.optional_audio);
587 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
588 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
591 media::VideoCaptureDevice::Names::const_iterator video_it =
592 physical_video_devices_.begin();
593 for (; video_it != physical_video_devices_.end(); ++video_it) {
594 std::string source_id = content::GetHMACForMediaDeviceID(
595 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
598 ASSERT_FALSE(source_id.empty());
599 StreamOptions options(true, true);
600 AddSourceIdConstraint(source_id, &options.optional_video);
603 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
604 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
608 // Test that generating a stream with an invalid mandatory video source id fail.
609 TEST_F(MediaStreamDispatcherHostTest,
610 GenerateStreamsWithInvalidMandatoryVideoSourceId) {
611 StreamOptions options(true, true);
612 AddSourceIdConstraint("invalid source id", &options.mandatory_video);
614 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options);
617 // Test that generating a stream with an invalid mandatory audio source id fail.
618 TEST_F(MediaStreamDispatcherHostTest,
619 GenerateStreamsWithInvalidMandatoryAudioSourceId) {
620 StreamOptions options(true, true);
621 AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
623 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options);
626 // Test that generating a stream with an invalid optional video source id
628 TEST_F(MediaStreamDispatcherHostTest,
629 GenerateStreamsWithInvalidOptionalVideoSourceId) {
630 StreamOptions options(true, true);
631 AddSourceIdConstraint("invalid source id", &options.optional_video);
634 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
637 // Test that generating a stream with an invalid optional audio source id
639 TEST_F(MediaStreamDispatcherHostTest,
640 GenerateStreamsWithInvalidOptionalAudioSourceId) {
641 StreamOptions options(true, true);
642 AddSourceIdConstraint("invalid source id", &options.optional_audio);
645 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
648 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
649 size_t number_of_fake_devices = physical_video_devices_.size();
650 media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(0);
651 media::FakeVideoCaptureDevice::GetDeviceNames(&physical_video_devices_);
652 StreamOptions options(true, true);
655 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
656 EXPECT_TRUE(host_->video_devices_.empty());
658 // Reset the number of fake devices for next test.
659 media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(number_of_fake_devices);
662 // Test that if a OnStopStreamDevice message is received for a device that has
663 // been opened in a MediaStream and by pepper, the device is only stopped for
665 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
666 StreamOptions options(false, true);
669 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
671 std::string stream_request_label = host_->label_;
672 StreamDeviceInfo video_device_info = host_->video_devices_.front();
673 ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
674 stream_request_label).size());
676 // Open the same device by Pepper.
677 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
678 video_device_info.device.id);
679 std::string open_device_request_label = host_->label_;
681 // Stop the device in the MediaStream.
682 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
684 EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
685 stream_request_label).size());
686 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
687 open_device_request_label).size());
690 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
691 StreamOptions options(true, true);
694 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
696 std::string request_label1 = host_->label_;
697 StreamDeviceInfo video_device_info = host_->video_devices_.front();
698 // Expect that 1 audio and 1 video device has been opened.
699 EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
700 request_label1).size());
702 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
703 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
704 request_label1).size());
706 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
707 std::string request_label2 = host_->label_;
709 StreamDeviceInfoArray request1_devices =
710 media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
711 StreamDeviceInfoArray request2_devices =
712 media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
714 ASSERT_EQ(1u, request1_devices.size());
715 ASSERT_EQ(2u, request2_devices.size());
717 // Test that the same audio device has been opened in both streams.
718 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
719 request2_devices[0]) ||
720 StreamDeviceInfo::IsEqual(request1_devices[0],
721 request2_devices[1]));
724 TEST_F(MediaStreamDispatcherHostTest,
725 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
726 StreamOptions options(false, true);
729 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
730 EXPECT_EQ(host_->video_devices_.size(), 1u);
732 // Generate a second stream.
733 EXPECT_CALL(*host_.get(),
734 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
736 base::RunLoop run_loop1;
737 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
738 run_loop1.QuitClosure());
740 // Stop the video stream device from stream 1 while waiting for the
741 // second stream to be generated.
742 host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
745 EXPECT_EQ(host_->video_devices_.size(), 1u);
748 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
749 StreamOptions options(false, true);
751 base::RunLoop run_loop;
753 // Create multiple GenerateStream requests.
755 for (size_t i = 1; i <= streams; ++i) {
756 host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
757 run_loop.QuitClosure());
760 // Calling OnChannelClosing() to cancel all the pending requests.
761 host_->OnChannelClosing();
762 run_loop.RunUntilIdle();
765 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
766 StreamOptions options(false, true);
768 // Create first group of streams.
769 size_t generated_streams = 3;
770 for (size_t i = 0; i < generated_streams; ++i) {
772 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
775 // Calling OnChannelClosing() to cancel all the pending/generated streams.
776 host_->OnChannelClosing();
777 base::RunLoop().RunUntilIdle();
780 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
781 StreamOptions options(false, true);
783 base::Closure close_callback;
784 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
785 EXPECT_CALL(*stream_ui, OnStarted(_))
786 .WillOnce(SaveArg<0>(&close_callback));
787 media_stream_manager_->UseFakeUI(stream_ui.PassAs<FakeMediaStreamUIProxy>());
789 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
791 EXPECT_EQ(host_->audio_devices_.size(), 0u);
792 EXPECT_EQ(host_->video_devices_.size(), 1u);
794 ASSERT_FALSE(close_callback.is_null());
795 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
796 close_callback.Run();
797 base::RunLoop().RunUntilIdle();
800 // Test that the dispatcher is notified if a video device that is in use is
802 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
803 size_t number_of_fake_devices = physical_video_devices_.size();
804 StreamOptions options(true, true);
806 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
807 EXPECT_EQ(host_->audio_devices_.size(), 1u);
808 EXPECT_EQ(host_->video_devices_.size(), 1u);
810 media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(0);
812 base::RunLoop run_loop;
813 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
814 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
815 media_stream_manager_->OnDevicesChanged(
816 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
820 media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(number_of_fake_devices);
823 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
824 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
825 MEDIA_DEVICE_AUDIO_CAPTURE);
828 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
829 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
830 MEDIA_DEVICE_VIDEO_CAPTURE);
833 }; // namespace content