Implement getMediaDevices.
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_dispatcher_host_unittest.cc
bloba09ffea38e48cdf218c4eb376e63fcec4a7edaa0
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.
5 #include <string>
6 #include <queue>
8 #include "base/bind.h"
9 #include "base/callback_helpers.h"
10 #include "base/command_line.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
15 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
16 #include "content/browser/renderer_host/media/media_stream_manager.h"
17 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
18 #include "content/browser/renderer_host/media/video_capture_manager.h"
19 #include "content/common/media/media_stream_messages.h"
20 #include "content/common/media/media_stream_options.h"
21 #include "content/public/browser/media_device_id.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/mock_resource_context.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "content/test/test_content_browser_client.h"
27 #include "content/test/test_content_client.h"
28 #include "ipc/ipc_message_macros.h"
29 #include "media/audio/mock_audio_manager.h"
30 #include "media/base/media_switches.h"
31 #include "media/video/capture/fake_video_capture_device_factory.h"
32 #include "net/url_request/url_request_context.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 using ::testing::_;
37 using ::testing::DeleteArg;
38 using ::testing::DoAll;
39 using ::testing::Return;
40 using ::testing::SaveArg;
42 const int kProcessId = 5;
43 const int kRenderId = 6;
44 const int kPageRequestId = 7;
46 namespace content {
48 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
49 public TestContentBrowserClient {
50 public:
51 MockMediaStreamDispatcherHost(
52 const ResourceContext::SaltCallback salt_callback,
53 const scoped_refptr<base::MessageLoopProxy>& message_loop,
54 MediaStreamManager* manager,
55 ResourceContext* resource_context)
56 : MediaStreamDispatcherHost(kProcessId, salt_callback, manager,
57 resource_context),
58 message_loop_(message_loop),
59 current_ipc_(NULL) {}
61 // A list of mock methods.
62 MOCK_METHOD4(OnStreamGenerated,
63 void(int routing_id, int request_id, int audio_array_size,
64 int video_array_size));
65 MOCK_METHOD3(OnStreamGenerationFailed, void(int routing_id,
66 int request_id,
67 MediaStreamRequestResult result));
68 MOCK_METHOD1(OnDeviceStopped, void(int routing_id));
69 MOCK_METHOD2(OnDeviceOpened, void(int routing_id, int request_id));
71 // Accessor to private functions.
72 void OnGenerateStream(int render_view_id,
73 int page_request_id,
74 const StreamOptions& components,
75 const GURL& security_origin,
76 const base::Closure& quit_closure) {
77 quit_closures_.push(quit_closure);
78 MediaStreamDispatcherHost::OnGenerateStream(
79 render_view_id, page_request_id, components, security_origin, false);
82 void OnStopStreamDevice(int render_view_id,
83 const std::string& device_id) {
84 MediaStreamDispatcherHost::OnStopStreamDevice(render_view_id, device_id);
87 void OnOpenDevice(int render_view_id,
88 int page_request_id,
89 const std::string& device_id,
90 MediaStreamType type,
91 const GURL& security_origin,
92 const base::Closure& quit_closure) {
93 quit_closures_.push(quit_closure);
94 MediaStreamDispatcherHost::OnOpenDevice(
95 render_view_id, page_request_id, device_id, type, security_origin);
98 void OnEnumerateDevices(int render_view_id,
99 int page_request_id,
100 MediaStreamType type,
101 const GURL& security_origin,
102 const base::Closure& quit_closure) {
103 quit_closures_.push(quit_closure);
104 MediaStreamDispatcherHost::OnEnumerateDevices(
105 render_view_id, page_request_id, type, security_origin);
108 std::string label_;
109 StreamDeviceInfoArray audio_devices_;
110 StreamDeviceInfoArray video_devices_;
111 StreamDeviceInfo opened_device_;
112 StreamDeviceInfoArray enumerated_devices_;
114 private:
115 virtual ~MockMediaStreamDispatcherHost() {}
117 // This method is used to dispatch IPC messages to the renderer. We intercept
118 // these messages here and dispatch to our mock methods to verify the
119 // conversation between this object and the renderer.
120 virtual bool Send(IPC::Message* message) OVERRIDE {
121 CHECK(message);
122 current_ipc_ = message;
124 // In this method we dispatch the messages to the according handlers as if
125 // we are the renderer.
126 bool handled = true;
127 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message)
128 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated,
129 OnStreamGeneratedInternal)
130 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed,
131 OnStreamGenerationFailedInternal)
132 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped, OnDeviceStoppedInternal)
133 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened, OnDeviceOpenedInternal)
134 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated, OnDevicesEnumerated)
135 IPC_MESSAGE_UNHANDLED(handled = false)
136 IPC_END_MESSAGE_MAP()
137 EXPECT_TRUE(handled);
139 delete message;
140 current_ipc_ = NULL;
141 return true;
144 // These handler methods do minimal things and delegate to the mock methods.
145 void OnStreamGeneratedInternal(
146 int request_id,
147 std::string label,
148 StreamDeviceInfoArray audio_device_list,
149 StreamDeviceInfoArray video_device_list) {
150 OnStreamGenerated(current_ipc_->routing_id(), request_id,
151 audio_device_list.size(), video_device_list.size());
152 // Notify that the event have occurred.
153 base::Closure quit_closure = quit_closures_.front();
154 quit_closures_.pop();
155 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
157 label_ = label;
158 audio_devices_ = audio_device_list;
159 video_devices_ = video_device_list;
162 void OnStreamGenerationFailedInternal(
163 int request_id,
164 content::MediaStreamRequestResult result) {
165 OnStreamGenerationFailed(current_ipc_->routing_id(), request_id, result);
166 if (!quit_closures_.empty()) {
167 base::Closure quit_closure = quit_closures_.front();
168 quit_closures_.pop();
169 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
172 label_= "";
175 void OnDeviceStoppedInternal(const std::string& label,
176 const content::StreamDeviceInfo& device) {
177 if (IsVideoMediaType(device.device.type))
178 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, video_devices_[0]));
179 if (IsAudioMediaType(device.device.type))
180 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, audio_devices_[0]));
182 OnDeviceStopped(current_ipc_->routing_id());
185 void OnDeviceOpenedInternal(int request_id,
186 const std::string& label,
187 const StreamDeviceInfo& device) {
188 base::Closure quit_closure = quit_closures_.front();
189 quit_closures_.pop();
190 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
191 label_ = label;
192 opened_device_ = device;
195 void OnDevicesEnumerated(int request_id,
196 const StreamDeviceInfoArray& devices) {
197 base::Closure quit_closure = quit_closures_.front();
198 quit_closures_.pop();
199 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
200 enumerated_devices_ = devices;
203 scoped_refptr<base::MessageLoopProxy> message_loop_;
204 IPC::Message* current_ipc_;
205 std::queue<base::Closure> quit_closures_;
208 class MockMediaStreamUIProxy : public FakeMediaStreamUIProxy {
209 public:
210 MOCK_METHOD2(
211 OnStarted,
212 void(const base::Closure& stop,
213 const MediaStreamUIProxy::WindowIdCallback& window_id_callback));
216 class MediaStreamDispatcherHostTest : public testing::Test {
217 public:
218 MediaStreamDispatcherHostTest()
219 : old_browser_client_(NULL),
220 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
221 origin_("https://test.com") {
222 audio_manager_.reset(
223 new media::MockAudioManager(base::MessageLoopProxy::current()));
224 // Make sure we use fake devices to avoid long delays.
225 CommandLine::ForCurrentProcess()->AppendSwitch(
226 switches::kUseFakeDeviceForMediaStream);
227 // Create our own MediaStreamManager.
228 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
229 video_capture_device_factory_ =
230 static_cast<media::FakeVideoCaptureDeviceFactory*>(
231 media_stream_manager_->video_capture_manager()
232 ->video_capture_device_factory());
233 DCHECK(video_capture_device_factory_);
235 MockResourceContext* mock_resource_context =
236 static_cast<MockResourceContext*>(
237 browser_context_.GetResourceContext());
238 mock_resource_context->set_mic_access(true);
239 mock_resource_context->set_camera_access(true);
241 host_ = new MockMediaStreamDispatcherHost(
242 mock_resource_context->GetMediaDeviceIDSalt(),
243 base::MessageLoopProxy::current(),
244 media_stream_manager_.get(),
245 mock_resource_context);
247 // Use the fake content client and browser.
248 content_client_.reset(new TestContentClient());
249 SetContentClient(content_client_.get());
250 old_browser_client_ = SetBrowserClientForTesting(host_.get());
253 virtual ~MediaStreamDispatcherHostTest() {
256 virtual void SetUp() OVERRIDE {
257 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
258 ASSERT_GT(physical_video_devices_.size(), 0u);
260 media_stream_manager_->audio_input_device_manager()->GetFakeDeviceNames(
261 &physical_audio_devices_);
262 ASSERT_GT(physical_audio_devices_.size(), 0u);
265 virtual void TearDown() OVERRIDE {
266 host_->OnChannelClosing();
269 protected:
270 virtual void SetupFakeUI(bool expect_started) {
271 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
272 if (expect_started) {
273 EXPECT_CALL(*stream_ui, OnStarted(_, _));
275 media_stream_manager_->UseFakeUI(
276 stream_ui.PassAs<FakeMediaStreamUIProxy>());
279 void GenerateStreamAndWaitForResult(int render_view_id,
280 int page_request_id,
281 const StreamOptions& options) {
282 base::RunLoop run_loop;
283 int expected_audio_array_size =
284 (options.audio_requested &&
285 physical_audio_devices_.size() > 0) ? 1 : 0;
286 int expected_video_array_size =
287 (options.video_requested &&
288 physical_video_devices_.size() > 0) ? 1 : 0;
289 EXPECT_CALL(*host_.get(), OnStreamGenerated(render_view_id, page_request_id,
290 expected_audio_array_size,
291 expected_video_array_size));
292 host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
293 run_loop.QuitClosure());
294 run_loop.Run();
295 EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
296 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
297 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
298 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
301 void GenerateStreamAndWaitForFailure(
302 int render_view_id,
303 int page_request_id,
304 const StreamOptions& options,
305 MediaStreamRequestResult expected_result) {
306 base::RunLoop run_loop;
307 EXPECT_CALL(*host_.get(),
308 OnStreamGenerationFailed(render_view_id,
309 page_request_id,
310 expected_result));
311 host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
312 run_loop.QuitClosure());
313 run_loop.Run();
316 void OpenVideoDeviceAndWaitForResult(int render_view_id,
317 int page_request_id,
318 const std::string& device_id) {
319 base::RunLoop run_loop;
320 host_->OnOpenDevice(render_view_id, page_request_id, device_id,
321 MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
322 run_loop.QuitClosure());
323 run_loop.Run();
324 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
325 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
328 void EnumerateDevicesAndWaitForResult(int render_view_id,
329 int page_request_id,
330 MediaStreamType type) {
331 base::RunLoop run_loop;
332 host_->OnEnumerateDevices(render_view_id, page_request_id, type, origin_,
333 run_loop.QuitClosure());
334 run_loop.Run();
335 ASSERT_FALSE(host_->enumerated_devices_.empty());
336 EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
337 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
340 bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
341 for (size_t i = 0; i < devices.size(); ++i) {
342 media::AudioDeviceNames::const_iterator audio_it =
343 physical_audio_devices_.begin();
344 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
345 if (audio_it->unique_id == devices[i].device.id)
346 return true;
348 media::VideoCaptureDevice::Names::const_iterator video_it =
349 physical_video_devices_.begin();
350 for (; video_it != physical_video_devices_.end(); ++video_it) {
351 if (video_it->id() == devices[i].device.id)
352 return true;
355 return false;
358 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
359 const GURL& origin) {
360 for (size_t i = 0; i < devices.size(); ++i) {
361 bool found_match = false;
362 media::AudioDeviceNames::const_iterator audio_it =
363 physical_audio_devices_.begin();
364 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
365 if (content::DoesMediaDeviceIDMatchHMAC(
366 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
367 origin,
368 devices[i].device.id,
369 audio_it->unique_id)) {
370 EXPECT_FALSE(found_match);
371 found_match = true;
374 media::VideoCaptureDevice::Names::const_iterator video_it =
375 physical_video_devices_.begin();
376 for (; video_it != physical_video_devices_.end(); ++video_it) {
377 if (content::DoesMediaDeviceIDMatchHMAC(
378 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
379 origin,
380 devices[i].device.id,
381 video_it->id())) {
382 EXPECT_FALSE(found_match);
383 found_match = true;
386 if (!found_match)
387 return false;
389 return true;
392 // Returns true if all devices have labels, false otherwise.
393 bool DoesContainLabels(const StreamDeviceInfoArray& devices) {
394 for (size_t i = 0; i < devices.size(); ++i) {
395 if (devices[i].device.name.empty())
396 return false;
398 return true;
401 // Returns true if no devices have labels, false otherwise.
402 bool DoesNotContainLabels(const StreamDeviceInfoArray& devices) {
403 for (size_t i = 0; i < devices.size(); ++i) {
404 if (!devices[i].device.name.empty())
405 return false;
407 return true;
410 void AddSourceIdConstraint(const std::string& source_id,
411 StreamOptions::Constraints* constraints) {
412 constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
413 source_id));
416 scoped_refptr<MockMediaStreamDispatcherHost> host_;
417 scoped_ptr<media::AudioManager> audio_manager_;
418 scoped_ptr<MediaStreamManager> media_stream_manager_;
419 ContentBrowserClient* old_browser_client_;
420 scoped_ptr<ContentClient> content_client_;
421 content::TestBrowserThreadBundle thread_bundle_;
422 content::TestBrowserContext browser_context_;
423 media::AudioDeviceNames physical_audio_devices_;
424 media::VideoCaptureDevice::Names physical_video_devices_;
425 GURL origin_;
426 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
429 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
430 StreamOptions options(false, true);
432 SetupFakeUI(true);
433 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
435 EXPECT_EQ(host_->audio_devices_.size(), 0u);
436 EXPECT_EQ(host_->video_devices_.size(), 1u);
439 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
440 StreamOptions options(true, false);
442 SetupFakeUI(true);
443 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
445 EXPECT_EQ(host_->audio_devices_.size(), 1u);
446 EXPECT_EQ(host_->video_devices_.size(), 0u);
449 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
450 StreamOptions options(false, false);
452 GenerateStreamAndWaitForFailure(
453 kRenderId,
454 kPageRequestId,
455 options,
456 MEDIA_DEVICE_INVALID_STATE);
459 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
460 StreamOptions options(true, true);
462 SetupFakeUI(true);
463 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
465 EXPECT_EQ(host_->audio_devices_.size(), 1u);
466 EXPECT_EQ(host_->video_devices_.size(), 1u);
469 // This test generates two streams with video only using the same render view
470 // id. The same capture device with the same device and session id is expected
471 // to be used.
472 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
473 StreamOptions options(false, true);
475 // Generate first stream.
476 SetupFakeUI(true);
477 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
479 // Check the latest generated stream.
480 EXPECT_EQ(host_->audio_devices_.size(), 0u);
481 EXPECT_EQ(host_->video_devices_.size(), 1u);
482 const std::string label1 = host_->label_;
483 const std::string device_id1 = host_->video_devices_.front().device.id;
484 const int session_id1 = host_->video_devices_.front().session_id;
486 // Generate second stream.
487 SetupFakeUI(true);
488 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
490 // Check the latest generated stream.
491 EXPECT_EQ(host_->audio_devices_.size(), 0u);
492 EXPECT_EQ(host_->video_devices_.size(), 1u);
493 const std::string label2 = host_->label_;
494 const std::string device_id2 = host_->video_devices_.front().device.id;
495 int session_id2 = host_->video_devices_.front().session_id;
496 EXPECT_EQ(device_id1, device_id2);
497 EXPECT_EQ(session_id1, session_id2);
498 EXPECT_NE(label1, label2);
501 TEST_F(MediaStreamDispatcherHostTest,
502 GenerateStreamAndOpenDeviceFromSameRenderId) {
503 StreamOptions options(false, true);
505 // Generate first stream.
506 SetupFakeUI(true);
507 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
509 EXPECT_EQ(host_->audio_devices_.size(), 0u);
510 EXPECT_EQ(host_->video_devices_.size(), 1u);
511 const std::string label1 = host_->label_;
512 const std::string device_id1 = host_->video_devices_.front().device.id;
513 const int session_id1 = host_->video_devices_.front().session_id;
515 // Generate second stream.
516 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
518 const std::string device_id2 = host_->opened_device_.device.id;
519 const int session_id2 = host_->opened_device_.session_id;
520 const std::string label2 = host_->label_;
522 EXPECT_EQ(device_id1, device_id2);
523 EXPECT_NE(session_id1, session_id2);
524 EXPECT_NE(label1, label2);
528 // This test generates two streams with video only using two separate render
529 // view ids. The same device id but different session ids are expected.
530 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
531 StreamOptions options(false, true);
533 // Generate first stream.
534 SetupFakeUI(true);
535 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
537 // Check the latest generated stream.
538 EXPECT_EQ(host_->audio_devices_.size(), 0u);
539 EXPECT_EQ(host_->video_devices_.size(), 1u);
540 const std::string label1 = host_->label_;
541 const std::string device_id1 = host_->video_devices_.front().device.id;
542 const int session_id1 = host_->video_devices_.front().session_id;
544 // Generate second stream from another render view.
545 SetupFakeUI(true);
546 GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
548 // Check the latest generated stream.
549 EXPECT_EQ(host_->audio_devices_.size(), 0u);
550 EXPECT_EQ(host_->video_devices_.size(), 1u);
551 const std::string label2 = host_->label_;
552 const std::string device_id2 = host_->video_devices_.front().device.id;
553 const int session_id2 = host_->video_devices_.front().session_id;
554 EXPECT_EQ(device_id1, device_id2);
555 EXPECT_NE(session_id1, session_id2);
556 EXPECT_NE(label1, label2);
559 // This test request two streams with video only without waiting for the first
560 // stream to be generated before requesting the second.
561 // The same device id and session ids are expected.
562 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
563 StreamOptions options(false, true);
565 // Generate first stream.
566 SetupFakeUI(true);
567 EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
569 // Generate second stream.
570 EXPECT_CALL(*host_.get(),
571 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
573 base::RunLoop run_loop1;
574 base::RunLoop run_loop2;
575 host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
576 run_loop1.QuitClosure());
577 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
578 run_loop2.QuitClosure());
580 run_loop1.Run();
581 run_loop2.Run();
584 // Test that we can generate streams where a mandatory sourceId is specified in
585 // the request.
586 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
587 ASSERT_GE(physical_audio_devices_.size(), 1u);
588 ASSERT_GE(physical_video_devices_.size(), 1u);
590 media::AudioDeviceNames::const_iterator audio_it =
591 physical_audio_devices_.begin();
592 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
593 std::string source_id = content::GetHMACForMediaDeviceID(
594 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
595 origin_,
596 audio_it->unique_id);
597 ASSERT_FALSE(source_id.empty());
598 StreamOptions options(true, true);
599 AddSourceIdConstraint(source_id, &options.mandatory_audio);
601 SetupFakeUI(true);
602 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
603 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
606 media::VideoCaptureDevice::Names::const_iterator video_it =
607 physical_video_devices_.begin();
608 for (; video_it != physical_video_devices_.end(); ++video_it) {
609 std::string source_id = content::GetHMACForMediaDeviceID(
610 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
611 origin_,
612 video_it->id());
613 ASSERT_FALSE(source_id.empty());
614 StreamOptions options(true, true);
615 AddSourceIdConstraint(source_id, &options.mandatory_video);
617 SetupFakeUI(true);
618 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
619 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
623 // Test that we can generate streams where a optional sourceId is specified in
624 // the request.
625 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
626 ASSERT_GE(physical_audio_devices_.size(), 1u);
627 ASSERT_GE(physical_video_devices_.size(), 1u);
629 media::AudioDeviceNames::const_iterator audio_it =
630 physical_audio_devices_.begin();
631 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
632 std::string source_id = content::GetHMACForMediaDeviceID(
633 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
634 origin_,
635 audio_it->unique_id);
636 ASSERT_FALSE(source_id.empty());
637 StreamOptions options(true, true);
638 AddSourceIdConstraint(source_id, &options.optional_audio);
640 SetupFakeUI(true);
641 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
642 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
645 media::VideoCaptureDevice::Names::const_iterator video_it =
646 physical_video_devices_.begin();
647 for (; video_it != physical_video_devices_.end(); ++video_it) {
648 std::string source_id = content::GetHMACForMediaDeviceID(
649 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
650 origin_,
651 video_it->id());
652 ASSERT_FALSE(source_id.empty());
653 StreamOptions options(true, true);
654 AddSourceIdConstraint(source_id, &options.optional_video);
656 SetupFakeUI(true);
657 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
658 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
662 // Test that generating a stream with an invalid mandatory video source id fail.
663 TEST_F(MediaStreamDispatcherHostTest,
664 GenerateStreamsWithInvalidMandatoryVideoSourceId) {
665 StreamOptions options(true, true);
666 AddSourceIdConstraint("invalid source id", &options.mandatory_video);
668 GenerateStreamAndWaitForFailure(
669 kRenderId,
670 kPageRequestId,
671 options,
672 MEDIA_DEVICE_NO_HARDWARE);
675 // Test that generating a stream with an invalid mandatory audio source id fail.
676 TEST_F(MediaStreamDispatcherHostTest,
677 GenerateStreamsWithInvalidMandatoryAudioSourceId) {
678 StreamOptions options(true, true);
679 AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
681 GenerateStreamAndWaitForFailure(
682 kRenderId,
683 kPageRequestId,
684 options,
685 MEDIA_DEVICE_NO_HARDWARE);
688 // Test that generating a stream with an invalid optional video source id
689 // succeed.
690 TEST_F(MediaStreamDispatcherHostTest,
691 GenerateStreamsWithInvalidOptionalVideoSourceId) {
692 StreamOptions options(true, true);
693 AddSourceIdConstraint("invalid source id", &options.optional_video);
695 SetupFakeUI(true);
696 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
699 // Test that generating a stream with an invalid optional audio source id
700 // succeed.
701 TEST_F(MediaStreamDispatcherHostTest,
702 GenerateStreamsWithInvalidOptionalAudioSourceId) {
703 StreamOptions options(true, true);
704 AddSourceIdConstraint("invalid source id", &options.optional_audio);
706 SetupFakeUI(true);
707 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
710 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
711 physical_video_devices_.clear();
712 video_capture_device_factory_->set_number_of_devices(0);
713 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
714 StreamOptions options(true, true);
716 SetupFakeUI(false);
717 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
718 MEDIA_DEVICE_NO_HARDWARE);
721 // Test that if a OnStopStreamDevice message is received for a device that has
722 // been opened in a MediaStream and by pepper, the device is only stopped for
723 // the MediaStream.
724 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
725 StreamOptions options(false, true);
727 SetupFakeUI(true);
728 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
730 std::string stream_request_label = host_->label_;
731 StreamDeviceInfo video_device_info = host_->video_devices_.front();
732 ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
733 stream_request_label).size());
735 // Open the same device by Pepper.
736 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
737 video_device_info.device.id);
738 std::string open_device_request_label = host_->label_;
740 // Stop the device in the MediaStream.
741 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
743 EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
744 stream_request_label).size());
745 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
746 open_device_request_label).size());
749 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
750 StreamOptions options(true, true);
752 SetupFakeUI(true);
753 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
755 std::string request_label1 = host_->label_;
756 StreamDeviceInfo video_device_info = host_->video_devices_.front();
757 // Expect that 1 audio and 1 video device has been opened.
758 EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
759 request_label1).size());
761 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
762 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
763 request_label1).size());
765 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
766 std::string request_label2 = host_->label_;
768 StreamDeviceInfoArray request1_devices =
769 media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
770 StreamDeviceInfoArray request2_devices =
771 media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
773 ASSERT_EQ(1u, request1_devices.size());
774 ASSERT_EQ(2u, request2_devices.size());
776 // Test that the same audio device has been opened in both streams.
777 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
778 request2_devices[0]) ||
779 StreamDeviceInfo::IsEqual(request1_devices[0],
780 request2_devices[1]));
783 TEST_F(MediaStreamDispatcherHostTest,
784 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
785 StreamOptions options(false, true);
787 SetupFakeUI(true);
788 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
789 EXPECT_EQ(host_->video_devices_.size(), 1u);
791 // Generate a second stream.
792 EXPECT_CALL(*host_.get(),
793 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
795 base::RunLoop run_loop1;
796 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
797 run_loop1.QuitClosure());
799 // Stop the video stream device from stream 1 while waiting for the
800 // second stream to be generated.
801 host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
802 run_loop1.Run();
804 EXPECT_EQ(host_->video_devices_.size(), 1u);
807 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
808 StreamOptions options(false, true);
810 base::RunLoop run_loop;
812 // Create multiple GenerateStream requests.
813 size_t streams = 5;
814 for (size_t i = 1; i <= streams; ++i) {
815 host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
816 run_loop.QuitClosure());
819 // Calling OnChannelClosing() to cancel all the pending requests.
820 host_->OnChannelClosing();
821 run_loop.RunUntilIdle();
824 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
825 StreamOptions options(false, true);
827 // Create first group of streams.
828 size_t generated_streams = 3;
829 for (size_t i = 0; i < generated_streams; ++i) {
830 SetupFakeUI(true);
831 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
834 // Calling OnChannelClosing() to cancel all the pending/generated streams.
835 host_->OnChannelClosing();
836 base::RunLoop().RunUntilIdle();
839 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
840 StreamOptions options(false, true);
842 base::Closure close_callback;
843 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
844 EXPECT_CALL(*stream_ui, OnStarted(_, _))
845 .WillOnce(SaveArg<0>(&close_callback));
846 media_stream_manager_->UseFakeUI(stream_ui.PassAs<FakeMediaStreamUIProxy>());
848 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
850 EXPECT_EQ(host_->audio_devices_.size(), 0u);
851 EXPECT_EQ(host_->video_devices_.size(), 1u);
853 ASSERT_FALSE(close_callback.is_null());
854 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
855 close_callback.Run();
856 base::RunLoop().RunUntilIdle();
859 // Test that the dispatcher is notified if a video device that is in use is
860 // being unplugged.
861 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
862 StreamOptions options(true, true);
863 SetupFakeUI(true);
864 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
865 EXPECT_EQ(host_->audio_devices_.size(), 1u);
866 EXPECT_EQ(host_->video_devices_.size(), 1u);
868 video_capture_device_factory_->set_number_of_devices(0);
870 base::RunLoop run_loop;
871 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
872 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
873 media_stream_manager_->OnDevicesChanged(
874 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
876 run_loop.Run();
879 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
880 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
881 MEDIA_DEVICE_AUDIO_CAPTURE);
882 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
885 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
886 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
887 MEDIA_DEVICE_VIDEO_CAPTURE);
888 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
891 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevicesNoAccess) {
892 MockResourceContext* mock_resource_context =
893 static_cast<MockResourceContext*>(browser_context_.GetResourceContext());
894 mock_resource_context->set_mic_access(false);
895 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
896 MEDIA_DEVICE_AUDIO_CAPTURE);
897 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
900 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevicesNoAccess) {
901 MockResourceContext* mock_resource_context =
902 static_cast<MockResourceContext*>(browser_context_.GetResourceContext());
903 mock_resource_context->set_camera_access(false);
904 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
905 MEDIA_DEVICE_VIDEO_CAPTURE);
906 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
909 }; // namespace content