Add a FrameHostMsg_BeginNavigation IPC
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_dispatcher_host_unittest.cc
bloba7edd38fc2536ba9445161d9cd9774c610efed11
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::InSequence;
40 using ::testing::Return;
41 using ::testing::SaveArg;
43 const int kProcessId = 5;
44 const int kRenderId = 6;
45 const int kPageRequestId = 7;
47 namespace content {
49 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
50 public TestContentBrowserClient {
51 public:
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,
58 resource_context),
59 message_loop_(message_loop),
60 current_ipc_(NULL) {}
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,
67 int request_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_view_id,
74 int page_request_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_view_id, page_request_id, components, security_origin, false);
83 void OnStopStreamDevice(int render_view_id,
84 const std::string& device_id) {
85 MediaStreamDispatcherHost::OnStopStreamDevice(render_view_id, device_id);
88 void OnOpenDevice(int render_view_id,
89 int page_request_id,
90 const std::string& device_id,
91 MediaStreamType type,
92 const GURL& security_origin,
93 const base::Closure& quit_closure) {
94 quit_closures_.push(quit_closure);
95 MediaStreamDispatcherHost::OnOpenDevice(
96 render_view_id, page_request_id, device_id, type, security_origin);
99 void OnEnumerateDevices(int render_view_id,
100 int page_request_id,
101 MediaStreamType type,
102 const GURL& security_origin,
103 bool hide_labels_if_no_access,
104 const base::Closure& quit_closure) {
105 quit_closures_.push(quit_closure);
106 MediaStreamDispatcherHost::OnEnumerateDevices(
107 render_view_id, page_request_id, type, security_origin,
108 hide_labels_if_no_access);
111 std::string label_;
112 StreamDeviceInfoArray audio_devices_;
113 StreamDeviceInfoArray video_devices_;
114 StreamDeviceInfo opened_device_;
115 StreamDeviceInfoArray enumerated_devices_;
117 private:
118 virtual ~MockMediaStreamDispatcherHost() {}
120 // This method is used to dispatch IPC messages to the renderer. We intercept
121 // these messages here and dispatch to our mock methods to verify the
122 // conversation between this object and the renderer.
123 virtual bool Send(IPC::Message* message) OVERRIDE {
124 CHECK(message);
125 current_ipc_ = message;
127 // In this method we dispatch the messages to the according handlers as if
128 // we are the renderer.
129 bool handled = true;
130 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message)
131 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated,
132 OnStreamGeneratedInternal)
133 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed,
134 OnStreamGenerationFailedInternal)
135 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped, OnDeviceStoppedInternal)
136 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened, OnDeviceOpenedInternal)
137 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated, OnDevicesEnumerated)
138 IPC_MESSAGE_UNHANDLED(handled = false)
139 IPC_END_MESSAGE_MAP()
140 EXPECT_TRUE(handled);
142 delete message;
143 current_ipc_ = NULL;
144 return true;
147 // These handler methods do minimal things and delegate to the mock methods.
148 void OnStreamGeneratedInternal(
149 int request_id,
150 std::string label,
151 StreamDeviceInfoArray audio_device_list,
152 StreamDeviceInfoArray video_device_list) {
153 OnStreamGenerated(current_ipc_->routing_id(), request_id,
154 audio_device_list.size(), video_device_list.size());
155 // Notify that the event have occurred.
156 base::Closure quit_closure = quit_closures_.front();
157 quit_closures_.pop();
158 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
160 label_ = label;
161 audio_devices_ = audio_device_list;
162 video_devices_ = video_device_list;
165 void OnStreamGenerationFailedInternal(
166 int request_id,
167 content::MediaStreamRequestResult result) {
168 OnStreamGenerationFailed(current_ipc_->routing_id(), request_id, result);
169 if (!quit_closures_.empty()) {
170 base::Closure quit_closure = quit_closures_.front();
171 quit_closures_.pop();
172 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
175 label_= "";
178 void OnDeviceStoppedInternal(const std::string& label,
179 const content::StreamDeviceInfo& device) {
180 if (IsVideoMediaType(device.device.type))
181 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, video_devices_[0]));
182 if (IsAudioInputMediaType(device.device.type))
183 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, audio_devices_[0]));
185 OnDeviceStopped(current_ipc_->routing_id());
188 void OnDeviceOpenedInternal(int request_id,
189 const std::string& label,
190 const StreamDeviceInfo& device) {
191 base::Closure quit_closure = quit_closures_.front();
192 quit_closures_.pop();
193 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
194 label_ = label;
195 opened_device_ = device;
198 void OnDevicesEnumerated(int request_id,
199 const StreamDeviceInfoArray& devices) {
200 base::Closure quit_closure = quit_closures_.front();
201 quit_closures_.pop();
202 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
203 enumerated_devices_ = devices;
206 scoped_refptr<base::MessageLoopProxy> message_loop_;
207 IPC::Message* current_ipc_;
208 std::queue<base::Closure> quit_closures_;
211 class MockMediaStreamUIProxy : public FakeMediaStreamUIProxy {
212 public:
213 MOCK_METHOD2(
214 OnStarted,
215 void(const base::Closure& stop,
216 const MediaStreamUIProxy::WindowIdCallback& window_id_callback));
219 class MediaStreamDispatcherHostTest : public testing::Test {
220 public:
221 MediaStreamDispatcherHostTest()
222 : old_browser_client_(NULL),
223 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
224 origin_("https://test.com") {
225 audio_manager_.reset(
226 new media::MockAudioManager(base::MessageLoopProxy::current()));
227 // Make sure we use fake devices to avoid long delays.
228 CommandLine::ForCurrentProcess()->AppendSwitch(
229 switches::kUseFakeDeviceForMediaStream);
230 // Create our own MediaStreamManager.
231 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
232 video_capture_device_factory_ =
233 static_cast<media::FakeVideoCaptureDeviceFactory*>(
234 media_stream_manager_->video_capture_manager()
235 ->video_capture_device_factory());
236 DCHECK(video_capture_device_factory_);
238 MockResourceContext* mock_resource_context =
239 static_cast<MockResourceContext*>(
240 browser_context_.GetResourceContext());
241 mock_resource_context->set_mic_access(true);
242 mock_resource_context->set_camera_access(true);
244 host_ = new MockMediaStreamDispatcherHost(
245 mock_resource_context->GetMediaDeviceIDSalt(),
246 base::MessageLoopProxy::current(),
247 media_stream_manager_.get(),
248 mock_resource_context);
250 // Use the fake content client and browser.
251 content_client_.reset(new TestContentClient());
252 SetContentClient(content_client_.get());
253 old_browser_client_ = SetBrowserClientForTesting(host_.get());
256 virtual ~MediaStreamDispatcherHostTest() {
259 virtual void SetUp() OVERRIDE {
260 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
261 ASSERT_GT(physical_video_devices_.size(), 0u);
263 media_stream_manager_->audio_input_device_manager()->GetFakeDeviceNames(
264 &physical_audio_devices_);
265 ASSERT_GT(physical_audio_devices_.size(), 0u);
268 virtual void TearDown() OVERRIDE {
269 host_->OnChannelClosing();
272 protected:
273 virtual void SetupFakeUI(bool expect_started) {
274 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
275 if (expect_started) {
276 EXPECT_CALL(*stream_ui, OnStarted(_, _));
278 media_stream_manager_->UseFakeUI(
279 stream_ui.PassAs<FakeMediaStreamUIProxy>());
282 void GenerateStreamAndWaitForResult(int render_view_id,
283 int page_request_id,
284 const StreamOptions& options) {
285 base::RunLoop run_loop;
286 int expected_audio_array_size =
287 (options.audio_requested &&
288 physical_audio_devices_.size() > 0) ? 1 : 0;
289 int expected_video_array_size =
290 (options.video_requested &&
291 physical_video_devices_.size() > 0) ? 1 : 0;
292 EXPECT_CALL(*host_.get(), OnStreamGenerated(render_view_id, page_request_id,
293 expected_audio_array_size,
294 expected_video_array_size));
295 host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
296 run_loop.QuitClosure());
297 run_loop.Run();
298 EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
299 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
300 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
301 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
304 void GenerateStreamAndWaitForFailure(
305 int render_view_id,
306 int page_request_id,
307 const StreamOptions& options,
308 MediaStreamRequestResult expected_result) {
309 base::RunLoop run_loop;
310 EXPECT_CALL(*host_.get(),
311 OnStreamGenerationFailed(render_view_id,
312 page_request_id,
313 expected_result));
314 host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
315 run_loop.QuitClosure());
316 run_loop.Run();
319 void OpenVideoDeviceAndWaitForResult(int render_view_id,
320 int page_request_id,
321 const std::string& device_id) {
322 base::RunLoop run_loop;
323 host_->OnOpenDevice(render_view_id, page_request_id, device_id,
324 MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
325 run_loop.QuitClosure());
326 run_loop.Run();
327 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
328 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
331 void EnumerateDevicesAndWaitForResult(int render_view_id,
332 int page_request_id,
333 MediaStreamType type,
334 bool hide_labels_if_no_access) {
335 base::RunLoop run_loop;
336 host_->OnEnumerateDevices(render_view_id, page_request_id, type, origin_,
337 hide_labels_if_no_access, run_loop.QuitClosure());
338 run_loop.Run();
339 ASSERT_FALSE(host_->enumerated_devices_.empty());
340 EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
341 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
344 bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
345 for (size_t i = 0; i < devices.size(); ++i) {
346 media::AudioDeviceNames::const_iterator audio_it =
347 physical_audio_devices_.begin();
348 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
349 if (audio_it->unique_id == devices[i].device.id)
350 return true;
352 media::VideoCaptureDevice::Names::const_iterator video_it =
353 physical_video_devices_.begin();
354 for (; video_it != physical_video_devices_.end(); ++video_it) {
355 if (video_it->id() == devices[i].device.id)
356 return true;
359 return false;
362 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
363 const GURL& origin) {
364 for (size_t i = 0; i < devices.size(); ++i) {
365 bool found_match = false;
366 media::AudioDeviceNames::const_iterator audio_it =
367 physical_audio_devices_.begin();
368 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
369 if (content::DoesMediaDeviceIDMatchHMAC(
370 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
371 origin,
372 devices[i].device.id,
373 audio_it->unique_id)) {
374 EXPECT_FALSE(found_match);
375 found_match = true;
378 media::VideoCaptureDevice::Names::const_iterator video_it =
379 physical_video_devices_.begin();
380 for (; video_it != physical_video_devices_.end(); ++video_it) {
381 if (content::DoesMediaDeviceIDMatchHMAC(
382 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
383 origin,
384 devices[i].device.id,
385 video_it->id())) {
386 EXPECT_FALSE(found_match);
387 found_match = true;
390 if (!found_match)
391 return false;
393 return true;
396 // Returns true if all devices have labels, false otherwise.
397 bool DoesContainLabels(const StreamDeviceInfoArray& devices) {
398 for (size_t i = 0; i < devices.size(); ++i) {
399 if (devices[i].device.name.empty())
400 return false;
402 return true;
405 // Returns true if no devices have labels, false otherwise.
406 bool DoesNotContainLabels(const StreamDeviceInfoArray& devices) {
407 for (size_t i = 0; i < devices.size(); ++i) {
408 if (!devices[i].device.name.empty())
409 return false;
411 return true;
414 void AddSourceIdConstraint(const std::string& source_id,
415 StreamOptions::Constraints* constraints) {
416 constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
417 source_id));
420 scoped_refptr<MockMediaStreamDispatcherHost> host_;
421 scoped_ptr<media::AudioManager> audio_manager_;
422 scoped_ptr<MediaStreamManager> media_stream_manager_;
423 ContentBrowserClient* old_browser_client_;
424 scoped_ptr<ContentClient> content_client_;
425 content::TestBrowserThreadBundle thread_bundle_;
426 content::TestBrowserContext browser_context_;
427 media::AudioDeviceNames physical_audio_devices_;
428 media::VideoCaptureDevice::Names physical_video_devices_;
429 GURL origin_;
430 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
433 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
434 StreamOptions options(false, true);
436 SetupFakeUI(true);
437 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
439 EXPECT_EQ(host_->audio_devices_.size(), 0u);
440 EXPECT_EQ(host_->video_devices_.size(), 1u);
443 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
444 StreamOptions options(true, false);
446 SetupFakeUI(true);
447 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
449 EXPECT_EQ(host_->audio_devices_.size(), 1u);
450 EXPECT_EQ(host_->video_devices_.size(), 0u);
453 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
454 StreamOptions options(false, false);
456 GenerateStreamAndWaitForFailure(
457 kRenderId,
458 kPageRequestId,
459 options,
460 MEDIA_DEVICE_INVALID_STATE);
463 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
464 StreamOptions options(true, true);
466 SetupFakeUI(true);
467 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
469 EXPECT_EQ(host_->audio_devices_.size(), 1u);
470 EXPECT_EQ(host_->video_devices_.size(), 1u);
473 // This test generates two streams with video only using the same render view
474 // id. The same capture device with the same device and session id is expected
475 // to be used.
476 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
477 StreamOptions options(false, true);
479 // Generate first stream.
480 SetupFakeUI(true);
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.
491 SetupFakeUI(true);
492 GenerateStreamAndWaitForResult(kRenderId, 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 int session_id2 = host_->video_devices_.front().session_id;
500 EXPECT_EQ(device_id1, device_id2);
501 EXPECT_EQ(session_id1, session_id2);
502 EXPECT_NE(label1, label2);
505 TEST_F(MediaStreamDispatcherHostTest,
506 GenerateStreamAndOpenDeviceFromSameRenderId) {
507 StreamOptions options(false, true);
509 // Generate first stream.
510 SetupFakeUI(true);
511 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
513 EXPECT_EQ(host_->audio_devices_.size(), 0u);
514 EXPECT_EQ(host_->video_devices_.size(), 1u);
515 const std::string label1 = host_->label_;
516 const std::string device_id1 = host_->video_devices_.front().device.id;
517 const int session_id1 = host_->video_devices_.front().session_id;
519 // Generate second stream.
520 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
522 const std::string device_id2 = host_->opened_device_.device.id;
523 const int session_id2 = host_->opened_device_.session_id;
524 const std::string label2 = host_->label_;
526 EXPECT_EQ(device_id1, device_id2);
527 EXPECT_NE(session_id1, session_id2);
528 EXPECT_NE(label1, label2);
532 // This test generates two streams with video only using two separate render
533 // view ids. The same device id but different session ids are expected.
534 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
535 StreamOptions options(false, true);
537 // Generate first stream.
538 SetupFakeUI(true);
539 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
541 // Check the latest generated stream.
542 EXPECT_EQ(host_->audio_devices_.size(), 0u);
543 EXPECT_EQ(host_->video_devices_.size(), 1u);
544 const std::string label1 = host_->label_;
545 const std::string device_id1 = host_->video_devices_.front().device.id;
546 const int session_id1 = host_->video_devices_.front().session_id;
548 // Generate second stream from another render view.
549 SetupFakeUI(true);
550 GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
552 // Check the latest generated stream.
553 EXPECT_EQ(host_->audio_devices_.size(), 0u);
554 EXPECT_EQ(host_->video_devices_.size(), 1u);
555 const std::string label2 = host_->label_;
556 const std::string device_id2 = host_->video_devices_.front().device.id;
557 const int session_id2 = host_->video_devices_.front().session_id;
558 EXPECT_EQ(device_id1, device_id2);
559 EXPECT_NE(session_id1, session_id2);
560 EXPECT_NE(label1, label2);
563 // This test request two streams with video only without waiting for the first
564 // stream to be generated before requesting the second.
565 // The same device id and session ids are expected.
566 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
567 StreamOptions options(false, true);
569 // Generate first stream.
570 SetupFakeUI(true);
572 InSequence s;
573 EXPECT_CALL(*host_.get(),
574 OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
576 // Generate second stream.
577 EXPECT_CALL(*host_.get(),
578 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
580 base::RunLoop run_loop1;
581 base::RunLoop run_loop2;
582 host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
583 run_loop1.QuitClosure());
584 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
585 run_loop2.QuitClosure());
587 run_loop1.Run();
588 run_loop2.Run();
591 // Test that we can generate streams where a mandatory sourceId is specified in
592 // the request.
593 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
594 ASSERT_GE(physical_audio_devices_.size(), 1u);
595 ASSERT_GE(physical_video_devices_.size(), 1u);
597 media::AudioDeviceNames::const_iterator audio_it =
598 physical_audio_devices_.begin();
599 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
600 std::string source_id = content::GetHMACForMediaDeviceID(
601 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
602 origin_,
603 audio_it->unique_id);
604 ASSERT_FALSE(source_id.empty());
605 StreamOptions options(true, true);
606 AddSourceIdConstraint(source_id, &options.mandatory_audio);
608 SetupFakeUI(true);
609 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
610 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
613 media::VideoCaptureDevice::Names::const_iterator video_it =
614 physical_video_devices_.begin();
615 for (; video_it != physical_video_devices_.end(); ++video_it) {
616 std::string source_id = content::GetHMACForMediaDeviceID(
617 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
618 origin_,
619 video_it->id());
620 ASSERT_FALSE(source_id.empty());
621 StreamOptions options(true, true);
622 AddSourceIdConstraint(source_id, &options.mandatory_video);
624 SetupFakeUI(true);
625 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
626 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
630 // Test that we can generate streams where a optional sourceId is specified in
631 // the request.
632 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
633 ASSERT_GE(physical_audio_devices_.size(), 1u);
634 ASSERT_GE(physical_video_devices_.size(), 1u);
636 media::AudioDeviceNames::const_iterator audio_it =
637 physical_audio_devices_.begin();
638 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
639 std::string source_id = content::GetHMACForMediaDeviceID(
640 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
641 origin_,
642 audio_it->unique_id);
643 ASSERT_FALSE(source_id.empty());
644 StreamOptions options(true, true);
645 AddSourceIdConstraint(source_id, &options.optional_audio);
647 SetupFakeUI(true);
648 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
649 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
652 media::VideoCaptureDevice::Names::const_iterator video_it =
653 physical_video_devices_.begin();
654 for (; video_it != physical_video_devices_.end(); ++video_it) {
655 std::string source_id = content::GetHMACForMediaDeviceID(
656 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
657 origin_,
658 video_it->id());
659 ASSERT_FALSE(source_id.empty());
660 StreamOptions options(true, true);
661 AddSourceIdConstraint(source_id, &options.optional_video);
663 SetupFakeUI(true);
664 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
665 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
669 // Test that generating a stream with an invalid mandatory video source id fail.
670 TEST_F(MediaStreamDispatcherHostTest,
671 GenerateStreamsWithInvalidMandatoryVideoSourceId) {
672 StreamOptions options(true, true);
673 AddSourceIdConstraint("invalid source id", &options.mandatory_video);
675 GenerateStreamAndWaitForFailure(
676 kRenderId,
677 kPageRequestId,
678 options,
679 MEDIA_DEVICE_NO_HARDWARE);
682 // Test that generating a stream with an invalid mandatory audio source id fail.
683 TEST_F(MediaStreamDispatcherHostTest,
684 GenerateStreamsWithInvalidMandatoryAudioSourceId) {
685 StreamOptions options(true, true);
686 AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
688 GenerateStreamAndWaitForFailure(
689 kRenderId,
690 kPageRequestId,
691 options,
692 MEDIA_DEVICE_NO_HARDWARE);
695 // Test that generating a stream with an invalid optional video source id
696 // succeed.
697 TEST_F(MediaStreamDispatcherHostTest,
698 GenerateStreamsWithInvalidOptionalVideoSourceId) {
699 StreamOptions options(true, true);
700 AddSourceIdConstraint("invalid source id", &options.optional_video);
702 SetupFakeUI(true);
703 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
706 // Test that generating a stream with an invalid optional audio source id
707 // succeed.
708 TEST_F(MediaStreamDispatcherHostTest,
709 GenerateStreamsWithInvalidOptionalAudioSourceId) {
710 StreamOptions options(true, true);
711 AddSourceIdConstraint("invalid source id", &options.optional_audio);
713 SetupFakeUI(true);
714 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
717 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
718 physical_video_devices_.clear();
719 video_capture_device_factory_->set_number_of_devices(0);
720 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
721 StreamOptions options(true, true);
723 SetupFakeUI(false);
724 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
725 MEDIA_DEVICE_NO_HARDWARE);
728 // Test that if a OnStopStreamDevice message is received for a device that has
729 // been opened in a MediaStream and by pepper, the device is only stopped for
730 // the MediaStream.
731 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
732 StreamOptions options(false, true);
734 SetupFakeUI(true);
735 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
737 std::string stream_request_label = host_->label_;
738 StreamDeviceInfo video_device_info = host_->video_devices_.front();
739 ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
740 stream_request_label).size());
742 // Open the same device by Pepper.
743 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
744 video_device_info.device.id);
745 std::string open_device_request_label = host_->label_;
747 // Stop the device in the MediaStream.
748 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
750 EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
751 stream_request_label).size());
752 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
753 open_device_request_label).size());
756 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
757 StreamOptions options(true, true);
759 SetupFakeUI(true);
760 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
762 std::string request_label1 = host_->label_;
763 StreamDeviceInfo video_device_info = host_->video_devices_.front();
764 // Expect that 1 audio and 1 video device has been opened.
765 EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
766 request_label1).size());
768 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
769 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
770 request_label1).size());
772 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
773 std::string request_label2 = host_->label_;
775 StreamDeviceInfoArray request1_devices =
776 media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
777 StreamDeviceInfoArray request2_devices =
778 media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
780 ASSERT_EQ(1u, request1_devices.size());
781 ASSERT_EQ(2u, request2_devices.size());
783 // Test that the same audio device has been opened in both streams.
784 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
785 request2_devices[0]) ||
786 StreamDeviceInfo::IsEqual(request1_devices[0],
787 request2_devices[1]));
790 TEST_F(MediaStreamDispatcherHostTest,
791 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
792 StreamOptions options(false, true);
794 SetupFakeUI(true);
795 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
796 EXPECT_EQ(host_->video_devices_.size(), 1u);
798 // Generate a second stream.
799 EXPECT_CALL(*host_.get(),
800 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
802 base::RunLoop run_loop1;
803 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
804 run_loop1.QuitClosure());
806 // Stop the video stream device from stream 1 while waiting for the
807 // second stream to be generated.
808 host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
809 run_loop1.Run();
811 EXPECT_EQ(host_->video_devices_.size(), 1u);
814 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
815 StreamOptions options(false, true);
817 base::RunLoop run_loop;
819 // Create multiple GenerateStream requests.
820 size_t streams = 5;
821 for (size_t i = 1; i <= streams; ++i) {
822 host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
823 run_loop.QuitClosure());
826 // Calling OnChannelClosing() to cancel all the pending requests.
827 host_->OnChannelClosing();
828 run_loop.RunUntilIdle();
831 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
832 StreamOptions options(false, true);
834 // Create first group of streams.
835 size_t generated_streams = 3;
836 for (size_t i = 0; i < generated_streams; ++i) {
837 SetupFakeUI(true);
838 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
841 // Calling OnChannelClosing() to cancel all the pending/generated streams.
842 host_->OnChannelClosing();
843 base::RunLoop().RunUntilIdle();
846 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
847 StreamOptions options(false, true);
849 base::Closure close_callback;
850 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
851 EXPECT_CALL(*stream_ui, OnStarted(_, _))
852 .WillOnce(SaveArg<0>(&close_callback));
853 media_stream_manager_->UseFakeUI(stream_ui.PassAs<FakeMediaStreamUIProxy>());
855 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
857 EXPECT_EQ(host_->audio_devices_.size(), 0u);
858 EXPECT_EQ(host_->video_devices_.size(), 1u);
860 ASSERT_FALSE(close_callback.is_null());
861 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
862 close_callback.Run();
863 base::RunLoop().RunUntilIdle();
866 // Test that the dispatcher is notified if a video device that is in use is
867 // being unplugged.
868 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
869 StreamOptions options(true, true);
870 SetupFakeUI(true);
871 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
872 EXPECT_EQ(host_->audio_devices_.size(), 1u);
873 EXPECT_EQ(host_->video_devices_.size(), 1u);
875 video_capture_device_factory_->set_number_of_devices(0);
877 base::RunLoop run_loop;
878 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
879 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
880 media_stream_manager_->OnDevicesChanged(
881 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
883 run_loop.Run();
886 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
887 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
888 MEDIA_DEVICE_AUDIO_CAPTURE, true);
889 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
892 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
893 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
894 MEDIA_DEVICE_VIDEO_CAPTURE, true);
895 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
898 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevicesNoAccessHideLabels) {
899 MockResourceContext* mock_resource_context =
900 static_cast<MockResourceContext*>(browser_context_.GetResourceContext());
901 mock_resource_context->set_mic_access(false);
902 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
903 MEDIA_DEVICE_AUDIO_CAPTURE, true);
904 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
907 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevicesNoAccessHideLabels) {
908 MockResourceContext* mock_resource_context =
909 static_cast<MockResourceContext*>(browser_context_.GetResourceContext());
910 mock_resource_context->set_camera_access(false);
911 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
912 MEDIA_DEVICE_VIDEO_CAPTURE, true);
913 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
916 TEST_F(MediaStreamDispatcherHostTest,
917 EnumerateAudioDevicesNoAccessNoHideLabels) {
918 MockResourceContext* mock_resource_context =
919 static_cast<MockResourceContext*>(browser_context_.GetResourceContext());
920 mock_resource_context->set_mic_access(false);
921 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
922 MEDIA_DEVICE_AUDIO_CAPTURE, false);
923 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
926 TEST_F(MediaStreamDispatcherHostTest,
927 EnumerateVideoDevicesNoAccessNoHideLabels) {
928 MockResourceContext* mock_resource_context =
929 static_cast<MockResourceContext*>(browser_context_.GetResourceContext());
930 mock_resource_context->set_camera_access(false);
931 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
932 MEDIA_DEVICE_VIDEO_CAPTURE, false);
933 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
936 }; // namespace content