Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_dispatcher_host_unittest.cc
bloba181899b44bffc39c85b3e4c22d5531f965785e2
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/media_stream_dispatcher_host.h"
15 #include "content/browser/renderer_host/media/media_stream_manager.h"
16 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
17 #include "content/browser/renderer_host/media/video_capture_manager.h"
18 #include "content/common/media/media_stream_messages.h"
19 #include "content/common/media/media_stream_options.h"
20 #include "content/public/browser/media_device_id.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/test/mock_resource_context.h"
23 #include "content/public/test/test_browser_context.h"
24 #include "content/public/test/test_browser_thread_bundle.h"
25 #include "content/test/test_content_browser_client.h"
26 #include "content/test/test_content_client.h"
27 #include "ipc/ipc_message_macros.h"
28 #include "media/audio/mock_audio_manager.h"
29 #include "media/video/capture/fake_video_capture_device_factory.h"
30 #include "net/url_request/url_request_context.h"
31 #include "testing/gmock/include/gmock/gmock.h"
32 #include "testing/gtest/include/gtest/gtest.h"
34 using ::testing::_;
35 using ::testing::DeleteArg;
36 using ::testing::DoAll;
37 using ::testing::Return;
38 using ::testing::SaveArg;
40 const int kProcessId = 5;
41 const int kRenderId = 6;
42 const int kPageRequestId = 7;
44 namespace content {
46 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
47 public TestContentBrowserClient {
48 public:
49 MockMediaStreamDispatcherHost(
50 const ResourceContext::SaltCallback salt_callback,
51 const scoped_refptr<base::MessageLoopProxy>& message_loop,
52 MediaStreamManager* manager)
53 : MediaStreamDispatcherHost(kProcessId, salt_callback, manager),
54 message_loop_(message_loop) {}
56 // A list of mock methods.
57 MOCK_METHOD4(OnStreamGenerated,
58 void(int routing_id, int request_id, int audio_array_size,
59 int video_array_size));
60 MOCK_METHOD3(OnStreamGenerationFailed, void(int routing_id,
61 int request_id,
62 MediaStreamRequestResult result));
63 MOCK_METHOD1(OnDeviceStopped, void(int routing_id));
64 MOCK_METHOD2(OnDeviceOpened, void(int routing_id, int request_id));
66 // Accessor to private functions.
67 void OnGenerateStream(int render_view_id,
68 int page_request_id,
69 const StreamOptions& components,
70 const GURL& security_origin,
71 const base::Closure& quit_closure) {
72 quit_closures_.push(quit_closure);
73 MediaStreamDispatcherHost::OnGenerateStream(
74 render_view_id, page_request_id, components, security_origin, false);
77 void OnStopStreamDevice(int render_view_id,
78 const std::string& device_id) {
79 MediaStreamDispatcherHost::OnStopStreamDevice(render_view_id, device_id);
82 void OnOpenDevice(int render_view_id,
83 int page_request_id,
84 const std::string& device_id,
85 MediaStreamType type,
86 const GURL& security_origin,
87 const base::Closure& quit_closure) {
88 quit_closures_.push(quit_closure);
89 MediaStreamDispatcherHost::OnOpenDevice(
90 render_view_id, page_request_id, device_id, type, security_origin);
93 void OnEnumerateDevices(int render_view_id,
94 int page_request_id,
95 MediaStreamType type,
96 const GURL& security_origin,
97 const base::Closure& quit_closure) {
98 quit_closures_.push(quit_closure);
99 MediaStreamDispatcherHost::OnEnumerateDevices(
100 render_view_id, page_request_id, type, security_origin);
103 std::string label_;
104 StreamDeviceInfoArray audio_devices_;
105 StreamDeviceInfoArray video_devices_;
106 StreamDeviceInfo opened_device_;
107 StreamDeviceInfoArray enumerated_devices_;
109 private:
110 virtual ~MockMediaStreamDispatcherHost() {}
112 // This method is used to dispatch IPC messages to the renderer. We intercept
113 // these messages here and dispatch to our mock methods to verify the
114 // conversation between this object and the renderer.
115 virtual bool Send(IPC::Message* message) OVERRIDE {
116 CHECK(message);
118 // In this method we dispatch the messages to the according handlers as if
119 // we are the renderer.
120 bool handled = true;
121 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message)
122 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated, OnStreamGenerated)
123 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed,
124 OnStreamGenerationFailed)
125 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped, OnDeviceStopped)
126 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened, OnDeviceOpened)
127 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated,
128 OnDevicesEnumerated)
129 IPC_MESSAGE_UNHANDLED(handled = false)
130 IPC_END_MESSAGE_MAP()
131 EXPECT_TRUE(handled);
133 delete message;
134 return true;
137 // These handler methods do minimal things and delegate to the mock methods.
138 void OnStreamGenerated(
139 const IPC::Message& msg,
140 int request_id,
141 std::string label,
142 StreamDeviceInfoArray audio_device_list,
143 StreamDeviceInfoArray video_device_list) {
144 OnStreamGenerated(msg.routing_id(), request_id, audio_device_list.size(),
145 video_device_list.size());
146 // Notify that the event have occurred.
147 base::Closure quit_closure = quit_closures_.front();
148 quit_closures_.pop();
149 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
151 label_ = label;
152 audio_devices_ = audio_device_list;
153 video_devices_ = video_device_list;
156 void OnStreamGenerationFailed(
157 const IPC::Message& msg,
158 int request_id,
159 content::MediaStreamRequestResult result) {
160 OnStreamGenerationFailed(msg.routing_id(), request_id, result);
161 if (!quit_closures_.empty()) {
162 base::Closure quit_closure = quit_closures_.front();
163 quit_closures_.pop();
164 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
167 label_= "";
170 void OnDeviceStopped(const IPC::Message& msg,
171 const std::string& label,
172 const content::StreamDeviceInfo& device) {
173 if (IsVideoMediaType(device.device.type))
174 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, video_devices_[0]));
175 if (IsAudioMediaType(device.device.type))
176 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, audio_devices_[0]));
178 OnDeviceStopped(msg.routing_id());
181 void OnDeviceOpened(const IPC::Message& msg,
182 int request_id,
183 const std::string& label,
184 const StreamDeviceInfo& device) {
185 base::Closure quit_closure = quit_closures_.front();
186 quit_closures_.pop();
187 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
188 label_ = label;
189 opened_device_ = device;
192 void OnDevicesEnumerated(const IPC::Message& msg,
193 int request_id,
194 const StreamDeviceInfoArray& devices) {
195 base::Closure quit_closure = quit_closures_.front();
196 quit_closures_.pop();
197 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
198 enumerated_devices_ = devices;
201 scoped_refptr<base::MessageLoopProxy> message_loop_;
203 std::queue<base::Closure> quit_closures_;
206 class MockMediaStreamUIProxy : public FakeMediaStreamUIProxy {
207 public:
208 MOCK_METHOD2(
209 OnStarted,
210 void(const base::Closure& stop,
211 const MediaStreamUIProxy::WindowIdCallback& window_id_callback));
214 class MediaStreamDispatcherHostTest : public testing::Test {
215 public:
216 MediaStreamDispatcherHostTest()
217 : old_browser_client_(NULL),
218 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
219 origin_("https://test.com") {
220 audio_manager_.reset(
221 new media::MockAudioManager(base::MessageLoopProxy::current()));
222 // Make sure we use fake devices to avoid long delays.
223 CommandLine::ForCurrentProcess()->AppendSwitch(
224 switches::kUseFakeDeviceForMediaStream);
225 // Create our own MediaStreamManager.
226 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
227 video_capture_device_factory_ =
228 static_cast<media::FakeVideoCaptureDeviceFactory*>(
229 media_stream_manager_->video_capture_manager()
230 ->video_capture_device_factory());
231 DCHECK(video_capture_device_factory_);
233 host_ = new MockMediaStreamDispatcherHost(
234 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
235 base::MessageLoopProxy::current(),
236 media_stream_manager_.get());
238 // Use the fake content client and browser.
239 content_client_.reset(new TestContentClient());
240 SetContentClient(content_client_.get());
241 old_browser_client_ = SetBrowserClientForTesting(host_.get());
244 virtual ~MediaStreamDispatcherHostTest() {
247 virtual void SetUp() OVERRIDE {
248 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
249 ASSERT_GT(physical_video_devices_.size(), 0u);
251 audio_manager_->GetAudioInputDeviceNames(&physical_audio_devices_);
252 ASSERT_GT(physical_audio_devices_.size(), 0u);
255 virtual void TearDown() OVERRIDE {
256 host_->OnChannelClosing();
259 protected:
260 virtual void SetupFakeUI(bool expect_started) {
261 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
262 if (expect_started) {
263 EXPECT_CALL(*stream_ui, OnStarted(_, _));
265 media_stream_manager_->UseFakeUI(
266 stream_ui.PassAs<FakeMediaStreamUIProxy>());
269 void GenerateStreamAndWaitForResult(int render_view_id,
270 int page_request_id,
271 const StreamOptions& options) {
272 base::RunLoop run_loop;
273 int expected_audio_array_size =
274 (options.audio_requested &&
275 physical_audio_devices_.size() > 0) ? 1 : 0;
276 int expected_video_array_size =
277 (options.video_requested &&
278 physical_video_devices_.size() > 0) ? 1 : 0;
279 EXPECT_CALL(*host_.get(), OnStreamGenerated(render_view_id, page_request_id,
280 expected_audio_array_size,
281 expected_video_array_size));
282 host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
283 run_loop.QuitClosure());
284 run_loop.Run();
285 EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
286 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
287 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
288 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
291 void GenerateStreamAndWaitForFailure(
292 int render_view_id,
293 int page_request_id,
294 const StreamOptions& options,
295 MediaStreamRequestResult expected_result) {
296 base::RunLoop run_loop;
297 EXPECT_CALL(*host_.get(),
298 OnStreamGenerationFailed(render_view_id,
299 page_request_id,
300 expected_result));
301 host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
302 run_loop.QuitClosure());
303 run_loop.Run();
306 void OpenVideoDeviceAndWaitForResult(int render_view_id,
307 int page_request_id,
308 const std::string& device_id) {
309 base::RunLoop run_loop;
310 host_->OnOpenDevice(render_view_id, page_request_id, device_id,
311 MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
312 run_loop.QuitClosure());
313 run_loop.Run();
314 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
315 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
318 void EnumerateDevicesAndWaitForResult(int render_view_id,
319 int page_request_id,
320 MediaStreamType type) {
321 base::RunLoop run_loop;
322 host_->OnEnumerateDevices(render_view_id, page_request_id, type, origin_,
323 run_loop.QuitClosure());
324 run_loop.Run();
325 ASSERT_FALSE(host_->enumerated_devices_.empty());
326 EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
327 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
330 bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
331 for (size_t i = 0; i < devices.size(); ++i) {
332 media::AudioDeviceNames::const_iterator audio_it =
333 physical_audio_devices_.begin();
334 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
335 if (audio_it->unique_id == devices[i].device.id)
336 return true;
338 media::VideoCaptureDevice::Names::const_iterator video_it =
339 physical_video_devices_.begin();
340 for (; video_it != physical_video_devices_.end(); ++video_it) {
341 if (video_it->id() == devices[i].device.id)
342 return true;
345 return false;
348 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
349 const GURL& origin) {
350 for (size_t i = 0; i < devices.size(); ++i) {
351 bool found_match = false;
352 media::AudioDeviceNames::const_iterator audio_it =
353 physical_audio_devices_.begin();
354 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
355 if (content::DoesMediaDeviceIDMatchHMAC(
356 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
357 origin,
358 devices[i].device.id,
359 audio_it->unique_id)) {
360 EXPECT_FALSE(found_match);
361 found_match = true;
364 media::VideoCaptureDevice::Names::const_iterator video_it =
365 physical_video_devices_.begin();
366 for (; video_it != physical_video_devices_.end(); ++video_it) {
367 if (content::DoesMediaDeviceIDMatchHMAC(
368 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
369 origin,
370 devices[i].device.id,
371 video_it->id())) {
372 EXPECT_FALSE(found_match);
373 found_match = true;
376 if (!found_match)
377 return false;
379 return true;
382 void AddSourceIdConstraint(const std::string& source_id,
383 StreamOptions::Constraints* constraints) {
384 constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
385 source_id));
388 scoped_refptr<MockMediaStreamDispatcherHost> host_;
389 scoped_ptr<media::AudioManager> audio_manager_;
390 scoped_ptr<MediaStreamManager> media_stream_manager_;
391 ContentBrowserClient* old_browser_client_;
392 scoped_ptr<ContentClient> content_client_;
393 content::TestBrowserThreadBundle thread_bundle_;
394 content::TestBrowserContext browser_context_;
395 media::AudioDeviceNames physical_audio_devices_;
396 media::VideoCaptureDevice::Names physical_video_devices_;
397 GURL origin_;
398 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
401 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
402 StreamOptions options(false, true);
404 SetupFakeUI(true);
405 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
407 EXPECT_EQ(host_->audio_devices_.size(), 0u);
408 EXPECT_EQ(host_->video_devices_.size(), 1u);
411 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
412 StreamOptions options(true, false);
414 SetupFakeUI(true);
415 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
417 EXPECT_EQ(host_->audio_devices_.size(), 1u);
418 EXPECT_EQ(host_->video_devices_.size(), 0u);
421 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
422 StreamOptions options(false, false);
424 GenerateStreamAndWaitForFailure(
425 kRenderId,
426 kPageRequestId,
427 options,
428 MEDIA_DEVICE_INVALID_STATE);
431 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
432 StreamOptions options(true, true);
434 SetupFakeUI(true);
435 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
437 EXPECT_EQ(host_->audio_devices_.size(), 1u);
438 EXPECT_EQ(host_->video_devices_.size(), 1u);
441 // This test generates two streams with video only using the same render view
442 // id. The same capture device with the same device and session id is expected
443 // to be used.
444 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
445 StreamOptions options(false, true);
447 // Generate first stream.
448 SetupFakeUI(true);
449 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
451 // Check the latest generated stream.
452 EXPECT_EQ(host_->audio_devices_.size(), 0u);
453 EXPECT_EQ(host_->video_devices_.size(), 1u);
454 const std::string label1 = host_->label_;
455 const std::string device_id1 = host_->video_devices_.front().device.id;
456 const int session_id1 = host_->video_devices_.front().session_id;
458 // Generate second stream.
459 SetupFakeUI(true);
460 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
462 // Check the latest generated stream.
463 EXPECT_EQ(host_->audio_devices_.size(), 0u);
464 EXPECT_EQ(host_->video_devices_.size(), 1u);
465 const std::string label2 = host_->label_;
466 const std::string device_id2 = host_->video_devices_.front().device.id;
467 int session_id2 = host_->video_devices_.front().session_id;
468 EXPECT_EQ(device_id1, device_id2);
469 EXPECT_EQ(session_id1, session_id2);
470 EXPECT_NE(label1, label2);
473 TEST_F(MediaStreamDispatcherHostTest,
474 GenerateStreamAndOpenDeviceFromSameRenderId) {
475 StreamOptions options(false, true);
477 // Generate first stream.
478 SetupFakeUI(true);
479 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
481 EXPECT_EQ(host_->audio_devices_.size(), 0u);
482 EXPECT_EQ(host_->video_devices_.size(), 1u);
483 const std::string label1 = host_->label_;
484 const std::string device_id1 = host_->video_devices_.front().device.id;
485 const int session_id1 = host_->video_devices_.front().session_id;
487 // Generate second stream.
488 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
490 const std::string device_id2 = host_->opened_device_.device.id;
491 const int session_id2 = host_->opened_device_.session_id;
492 const std::string label2 = host_->label_;
494 EXPECT_EQ(device_id1, device_id2);
495 EXPECT_NE(session_id1, session_id2);
496 EXPECT_NE(label1, label2);
500 // This test generates two streams with video only using two separate render
501 // view ids. The same device id but different session ids are expected.
502 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
503 StreamOptions options(false, true);
505 // Generate first stream.
506 SetupFakeUI(true);
507 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
509 // Check the latest generated stream.
510 EXPECT_EQ(host_->audio_devices_.size(), 0u);
511 EXPECT_EQ(host_->video_devices_.size(), 1u);
512 const std::string label1 = host_->label_;
513 const std::string device_id1 = host_->video_devices_.front().device.id;
514 const int session_id1 = host_->video_devices_.front().session_id;
516 // Generate second stream from another render view.
517 SetupFakeUI(true);
518 GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
520 // Check the latest generated stream.
521 EXPECT_EQ(host_->audio_devices_.size(), 0u);
522 EXPECT_EQ(host_->video_devices_.size(), 1u);
523 const std::string label2 = host_->label_;
524 const std::string device_id2 = host_->video_devices_.front().device.id;
525 const int session_id2 = host_->video_devices_.front().session_id;
526 EXPECT_EQ(device_id1, device_id2);
527 EXPECT_NE(session_id1, session_id2);
528 EXPECT_NE(label1, label2);
531 // This test request two streams with video only without waiting for the first
532 // stream to be generated before requesting the second.
533 // The same device id and session ids are expected.
534 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
535 StreamOptions options(false, true);
537 // Generate first stream.
538 SetupFakeUI(true);
539 EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
541 // Generate second stream.
542 EXPECT_CALL(*host_.get(),
543 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
545 base::RunLoop run_loop1;
546 base::RunLoop run_loop2;
547 host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
548 run_loop1.QuitClosure());
549 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
550 run_loop2.QuitClosure());
552 run_loop1.Run();
553 run_loop2.Run();
556 // Test that we can generate streams where a mandatory sourceId is specified in
557 // the request.
558 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
559 ASSERT_GE(physical_audio_devices_.size(), 1u);
560 ASSERT_GE(physical_video_devices_.size(), 1u);
562 media::AudioDeviceNames::const_iterator audio_it =
563 physical_audio_devices_.begin();
564 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
565 std::string source_id = content::GetHMACForMediaDeviceID(
566 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
567 origin_,
568 audio_it->unique_id);
569 ASSERT_FALSE(source_id.empty());
570 StreamOptions options(true, true);
571 AddSourceIdConstraint(source_id, &options.mandatory_audio);
573 SetupFakeUI(true);
574 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
575 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
578 media::VideoCaptureDevice::Names::const_iterator video_it =
579 physical_video_devices_.begin();
580 for (; video_it != physical_video_devices_.end(); ++video_it) {
581 std::string source_id = content::GetHMACForMediaDeviceID(
582 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
583 origin_,
584 video_it->id());
585 ASSERT_FALSE(source_id.empty());
586 StreamOptions options(true, true);
587 AddSourceIdConstraint(source_id, &options.mandatory_video);
589 SetupFakeUI(true);
590 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
591 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
595 // Test that we can generate streams where a optional sourceId is specified in
596 // the request.
597 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
598 ASSERT_GE(physical_audio_devices_.size(), 1u);
599 ASSERT_GE(physical_video_devices_.size(), 1u);
601 media::AudioDeviceNames::const_iterator audio_it =
602 physical_audio_devices_.begin();
603 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
604 std::string source_id = content::GetHMACForMediaDeviceID(
605 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
606 origin_,
607 audio_it->unique_id);
608 ASSERT_FALSE(source_id.empty());
609 StreamOptions options(true, true);
610 AddSourceIdConstraint(source_id, &options.optional_audio);
612 SetupFakeUI(true);
613 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
614 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
617 media::VideoCaptureDevice::Names::const_iterator video_it =
618 physical_video_devices_.begin();
619 for (; video_it != physical_video_devices_.end(); ++video_it) {
620 std::string source_id = content::GetHMACForMediaDeviceID(
621 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
622 origin_,
623 video_it->id());
624 ASSERT_FALSE(source_id.empty());
625 StreamOptions options(true, true);
626 AddSourceIdConstraint(source_id, &options.optional_video);
628 SetupFakeUI(true);
629 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
630 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
634 // Test that generating a stream with an invalid mandatory video source id fail.
635 TEST_F(MediaStreamDispatcherHostTest,
636 GenerateStreamsWithInvalidMandatoryVideoSourceId) {
637 StreamOptions options(true, true);
638 AddSourceIdConstraint("invalid source id", &options.mandatory_video);
640 GenerateStreamAndWaitForFailure(
641 kRenderId,
642 kPageRequestId,
643 options,
644 MEDIA_DEVICE_NO_HARDWARE);
647 // Test that generating a stream with an invalid mandatory audio source id fail.
648 TEST_F(MediaStreamDispatcherHostTest,
649 GenerateStreamsWithInvalidMandatoryAudioSourceId) {
650 StreamOptions options(true, true);
651 AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
653 GenerateStreamAndWaitForFailure(
654 kRenderId,
655 kPageRequestId,
656 options,
657 MEDIA_DEVICE_NO_HARDWARE);
660 // Test that generating a stream with an invalid optional video source id
661 // succeed.
662 TEST_F(MediaStreamDispatcherHostTest,
663 GenerateStreamsWithInvalidOptionalVideoSourceId) {
664 StreamOptions options(true, true);
665 AddSourceIdConstraint("invalid source id", &options.optional_video);
667 SetupFakeUI(true);
668 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
671 // Test that generating a stream with an invalid optional audio source id
672 // succeed.
673 TEST_F(MediaStreamDispatcherHostTest,
674 GenerateStreamsWithInvalidOptionalAudioSourceId) {
675 StreamOptions options(true, true);
676 AddSourceIdConstraint("invalid source id", &options.optional_audio);
678 SetupFakeUI(true);
679 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
682 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
683 physical_video_devices_.clear();
684 video_capture_device_factory_->set_number_of_devices(0);
685 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
686 StreamOptions options(true, true);
688 SetupFakeUI(false);
689 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
690 MEDIA_DEVICE_NO_HARDWARE);
693 // Test that if a OnStopStreamDevice message is received for a device that has
694 // been opened in a MediaStream and by pepper, the device is only stopped for
695 // the MediaStream.
696 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
697 StreamOptions options(false, true);
699 SetupFakeUI(true);
700 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
702 std::string stream_request_label = host_->label_;
703 StreamDeviceInfo video_device_info = host_->video_devices_.front();
704 ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
705 stream_request_label).size());
707 // Open the same device by Pepper.
708 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
709 video_device_info.device.id);
710 std::string open_device_request_label = host_->label_;
712 // Stop the device in the MediaStream.
713 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
715 EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
716 stream_request_label).size());
717 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
718 open_device_request_label).size());
721 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
722 StreamOptions options(true, true);
724 SetupFakeUI(true);
725 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
727 std::string request_label1 = host_->label_;
728 StreamDeviceInfo video_device_info = host_->video_devices_.front();
729 // Expect that 1 audio and 1 video device has been opened.
730 EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
731 request_label1).size());
733 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
734 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
735 request_label1).size());
737 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
738 std::string request_label2 = host_->label_;
740 StreamDeviceInfoArray request1_devices =
741 media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
742 StreamDeviceInfoArray request2_devices =
743 media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
745 ASSERT_EQ(1u, request1_devices.size());
746 ASSERT_EQ(2u, request2_devices.size());
748 // Test that the same audio device has been opened in both streams.
749 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
750 request2_devices[0]) ||
751 StreamDeviceInfo::IsEqual(request1_devices[0],
752 request2_devices[1]));
755 TEST_F(MediaStreamDispatcherHostTest,
756 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
757 StreamOptions options(false, true);
759 SetupFakeUI(true);
760 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
761 EXPECT_EQ(host_->video_devices_.size(), 1u);
763 // Generate a second stream.
764 EXPECT_CALL(*host_.get(),
765 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
767 base::RunLoop run_loop1;
768 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
769 run_loop1.QuitClosure());
771 // Stop the video stream device from stream 1 while waiting for the
772 // second stream to be generated.
773 host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
774 run_loop1.Run();
776 EXPECT_EQ(host_->video_devices_.size(), 1u);
779 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
780 StreamOptions options(false, true);
782 base::RunLoop run_loop;
784 // Create multiple GenerateStream requests.
785 size_t streams = 5;
786 for (size_t i = 1; i <= streams; ++i) {
787 host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
788 run_loop.QuitClosure());
791 // Calling OnChannelClosing() to cancel all the pending requests.
792 host_->OnChannelClosing();
793 run_loop.RunUntilIdle();
796 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
797 StreamOptions options(false, true);
799 // Create first group of streams.
800 size_t generated_streams = 3;
801 for (size_t i = 0; i < generated_streams; ++i) {
802 SetupFakeUI(true);
803 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
806 // Calling OnChannelClosing() to cancel all the pending/generated streams.
807 host_->OnChannelClosing();
808 base::RunLoop().RunUntilIdle();
811 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
812 StreamOptions options(false, true);
814 base::Closure close_callback;
815 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
816 EXPECT_CALL(*stream_ui, OnStarted(_, _))
817 .WillOnce(SaveArg<0>(&close_callback));
818 media_stream_manager_->UseFakeUI(stream_ui.PassAs<FakeMediaStreamUIProxy>());
820 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
822 EXPECT_EQ(host_->audio_devices_.size(), 0u);
823 EXPECT_EQ(host_->video_devices_.size(), 1u);
825 ASSERT_FALSE(close_callback.is_null());
826 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
827 close_callback.Run();
828 base::RunLoop().RunUntilIdle();
831 // Test that the dispatcher is notified if a video device that is in use is
832 // being unplugged.
833 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
834 StreamOptions options(true, true);
835 SetupFakeUI(true);
836 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
837 EXPECT_EQ(host_->audio_devices_.size(), 1u);
838 EXPECT_EQ(host_->video_devices_.size(), 1u);
840 video_capture_device_factory_->set_number_of_devices(0);
842 base::RunLoop run_loop;
843 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
844 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
845 media_stream_manager_->OnDevicesChanged(
846 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
848 run_loop.Run();
851 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
852 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
853 MEDIA_DEVICE_AUDIO_CAPTURE);
856 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
857 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
858 MEDIA_DEVICE_VIDEO_CAPTURE);
861 }; // namespace content