Use scoped_ptr::Pass instead of scoped_ptr::PassAs<T>.
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_dispatcher_host_unittest.cc
blob1bad313bfd7c78955a475560b0c046578a9d4df1
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 #if defined(OS_CHROMEOS)
37 #include "chromeos/audio/cras_audio_handler.h"
38 #endif
40 using ::testing::_;
41 using ::testing::DeleteArg;
42 using ::testing::DoAll;
43 using ::testing::InSequence;
44 using ::testing::Return;
45 using ::testing::SaveArg;
47 const int kProcessId = 5;
48 const int kRenderId = 6;
49 const int kPageRequestId = 7;
51 namespace content {
53 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
54 public TestContentBrowserClient {
55 public:
56 MockMediaStreamDispatcherHost(
57 const ResourceContext::SaltCallback salt_callback,
58 const scoped_refptr<base::MessageLoopProxy>& message_loop,
59 MediaStreamManager* manager)
60 : MediaStreamDispatcherHost(kProcessId, salt_callback, manager),
61 message_loop_(message_loop),
62 current_ipc_(NULL) {}
64 // A list of mock methods.
65 MOCK_METHOD4(OnStreamGenerated,
66 void(int routing_id, int request_id, int audio_array_size,
67 int video_array_size));
68 MOCK_METHOD3(OnStreamGenerationFailed, void(int routing_id,
69 int request_id,
70 MediaStreamRequestResult result));
71 MOCK_METHOD1(OnDeviceStopped, void(int routing_id));
72 MOCK_METHOD2(OnDeviceOpened, void(int routing_id, int request_id));
74 // Accessor to private functions.
75 void OnGenerateStream(int render_frame_id,
76 int page_request_id,
77 const StreamOptions& components,
78 const GURL& security_origin,
79 const base::Closure& quit_closure) {
80 quit_closures_.push(quit_closure);
81 MediaStreamDispatcherHost::OnGenerateStream(
82 render_frame_id, page_request_id, components, security_origin, false);
85 void OnStopStreamDevice(int render_frame_id,
86 const std::string& device_id) {
87 MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id, device_id);
90 void OnOpenDevice(int render_frame_id,
91 int page_request_id,
92 const std::string& device_id,
93 MediaStreamType type,
94 const GURL& security_origin,
95 const base::Closure& quit_closure) {
96 quit_closures_.push(quit_closure);
97 MediaStreamDispatcherHost::OnOpenDevice(
98 render_frame_id, page_request_id, device_id, type, security_origin);
101 void OnEnumerateDevices(int render_frame_id,
102 int page_request_id,
103 MediaStreamType type,
104 const GURL& security_origin,
105 const base::Closure& quit_closure) {
106 quit_closures_.push(quit_closure);
107 MediaStreamDispatcherHost::OnEnumerateDevices(
108 render_frame_id, page_request_id, type, security_origin);
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 base::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());
242 host_ = new MockMediaStreamDispatcherHost(
243 mock_resource_context->GetMediaDeviceIDSalt(),
244 base::MessageLoopProxy::current(),
245 media_stream_manager_.get());
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());
252 #if defined(OS_CHROMEOS)
253 chromeos::CrasAudioHandler::InitializeForTesting();
254 #endif
257 virtual ~MediaStreamDispatcherHostTest() {
258 #if defined(OS_CHROMEOS)
259 chromeos::CrasAudioHandler::Shutdown();
260 #endif
263 virtual void SetUp() override {
264 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
265 ASSERT_GT(physical_video_devices_.size(), 0u);
267 media_stream_manager_->audio_input_device_manager()->GetFakeDeviceNames(
268 &physical_audio_devices_);
269 ASSERT_GT(physical_audio_devices_.size(), 0u);
272 virtual void TearDown() override {
273 host_->OnChannelClosing();
276 protected:
277 virtual void SetupFakeUI(bool expect_started) {
278 stream_ui_ = new MockMediaStreamUIProxy();
279 if (expect_started) {
280 EXPECT_CALL(*stream_ui_, OnStarted(_, _));
282 media_stream_manager_->UseFakeUI(
283 scoped_ptr<FakeMediaStreamUIProxy>(stream_ui_));
286 void GenerateStreamAndWaitForResult(int render_frame_id,
287 int page_request_id,
288 const StreamOptions& options) {
289 base::RunLoop run_loop;
290 int expected_audio_array_size =
291 (options.audio_requested &&
292 physical_audio_devices_.size() > 0) ? 1 : 0;
293 int expected_video_array_size =
294 (options.video_requested &&
295 physical_video_devices_.size() > 0) ? 1 : 0;
296 EXPECT_CALL(*host_.get(), OnStreamGenerated(render_frame_id,
297 page_request_id,
298 expected_audio_array_size,
299 expected_video_array_size));
300 host_->OnGenerateStream(render_frame_id, page_request_id, options, origin_,
301 run_loop.QuitClosure());
302 run_loop.Run();
303 EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
304 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
305 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
306 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
309 void GenerateStreamAndWaitForFailure(
310 int render_frame_id,
311 int page_request_id,
312 const StreamOptions& options,
313 MediaStreamRequestResult expected_result) {
314 base::RunLoop run_loop;
315 EXPECT_CALL(*host_.get(),
316 OnStreamGenerationFailed(render_frame_id,
317 page_request_id,
318 expected_result));
319 host_->OnGenerateStream(render_frame_id, page_request_id, options,
320 origin_, run_loop.QuitClosure());
321 run_loop.Run();
324 void OpenVideoDeviceAndWaitForResult(int render_frame_id,
325 int page_request_id,
326 const std::string& device_id) {
327 base::RunLoop run_loop;
328 host_->OnOpenDevice(render_frame_id, page_request_id, device_id,
329 MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
330 run_loop.QuitClosure());
331 run_loop.Run();
332 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
333 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
336 void EnumerateDevicesAndWaitForResult(int render_frame_id,
337 int page_request_id,
338 MediaStreamType type) {
339 base::RunLoop run_loop;
340 host_->OnEnumerateDevices(render_frame_id, page_request_id, type, origin_,
341 run_loop.QuitClosure());
342 run_loop.Run();
343 ASSERT_FALSE(host_->enumerated_devices_.empty());
344 EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
345 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
348 bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
349 for (size_t i = 0; i < devices.size(); ++i) {
350 media::AudioDeviceNames::const_iterator audio_it =
351 physical_audio_devices_.begin();
352 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
353 if (audio_it->unique_id == devices[i].device.id)
354 return true;
356 media::VideoCaptureDevice::Names::const_iterator video_it =
357 physical_video_devices_.begin();
358 for (; video_it != physical_video_devices_.end(); ++video_it) {
359 if (video_it->id() == devices[i].device.id)
360 return true;
363 return false;
366 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
367 const GURL& origin) {
368 for (size_t i = 0; i < devices.size(); ++i) {
369 bool found_match = false;
370 media::AudioDeviceNames::const_iterator audio_it =
371 physical_audio_devices_.begin();
372 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
373 if (content::DoesMediaDeviceIDMatchHMAC(
374 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
375 origin,
376 devices[i].device.id,
377 audio_it->unique_id)) {
378 EXPECT_FALSE(found_match);
379 found_match = true;
382 media::VideoCaptureDevice::Names::const_iterator video_it =
383 physical_video_devices_.begin();
384 for (; video_it != physical_video_devices_.end(); ++video_it) {
385 if (content::DoesMediaDeviceIDMatchHMAC(
386 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
387 origin,
388 devices[i].device.id,
389 video_it->id())) {
390 EXPECT_FALSE(found_match);
391 found_match = true;
394 if (!found_match)
395 return false;
397 return true;
400 // Returns true if all devices have labels, false otherwise.
401 bool DoesContainLabels(const StreamDeviceInfoArray& devices) {
402 for (size_t i = 0; i < devices.size(); ++i) {
403 if (devices[i].device.name.empty())
404 return false;
406 return true;
409 // Returns true if no devices have labels, false otherwise.
410 bool DoesNotContainLabels(const StreamDeviceInfoArray& devices) {
411 for (size_t i = 0; i < devices.size(); ++i) {
412 if (!devices[i].device.name.empty())
413 return false;
415 return true;
418 void AddSourceIdConstraint(const std::string& source_id,
419 StreamOptions::Constraints* constraints) {
420 constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
421 source_id));
424 scoped_refptr<MockMediaStreamDispatcherHost> host_;
425 scoped_ptr<media::AudioManager> audio_manager_;
426 scoped_ptr<MediaStreamManager> media_stream_manager_;
427 MockMediaStreamUIProxy* stream_ui_;
428 ContentBrowserClient* old_browser_client_;
429 scoped_ptr<ContentClient> content_client_;
430 content::TestBrowserThreadBundle thread_bundle_;
431 content::TestBrowserContext browser_context_;
432 media::AudioDeviceNames physical_audio_devices_;
433 media::VideoCaptureDevice::Names physical_video_devices_;
434 GURL origin_;
435 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
438 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
439 StreamOptions options(false, true);
441 SetupFakeUI(true);
442 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
444 EXPECT_EQ(host_->audio_devices_.size(), 0u);
445 EXPECT_EQ(host_->video_devices_.size(), 1u);
448 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
449 StreamOptions options(true, false);
451 SetupFakeUI(true);
452 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
454 EXPECT_EQ(host_->audio_devices_.size(), 1u);
455 EXPECT_EQ(host_->video_devices_.size(), 0u);
458 // This test simulates a shutdown scenario: we don't setup a fake UI proxy for
459 // MediaStreamManager, so it will create an ordinary one which will not find
460 // a RenderFrameHostDelegate. This normally should only be the case at shutdown.
461 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
462 StreamOptions options(false, false);
464 GenerateStreamAndWaitForFailure(
465 kRenderId,
466 kPageRequestId,
467 options,
468 MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN);
471 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
472 StreamOptions options(true, true);
474 SetupFakeUI(true);
475 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
477 EXPECT_EQ(host_->audio_devices_.size(), 1u);
478 EXPECT_EQ(host_->video_devices_.size(), 1u);
481 // This test generates two streams with video only using the same render frame
482 // id. The same capture device with the same device and session id is expected
483 // to be used.
484 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
485 StreamOptions options(false, true);
487 // Generate first stream.
488 SetupFakeUI(true);
489 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
491 // Check the latest generated stream.
492 EXPECT_EQ(host_->audio_devices_.size(), 0u);
493 EXPECT_EQ(host_->video_devices_.size(), 1u);
494 const std::string label1 = host_->label_;
495 const std::string device_id1 = host_->video_devices_.front().device.id;
496 const int session_id1 = host_->video_devices_.front().session_id;
498 // Generate second stream.
499 SetupFakeUI(true);
500 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
502 // Check the latest generated stream.
503 EXPECT_EQ(host_->audio_devices_.size(), 0u);
504 EXPECT_EQ(host_->video_devices_.size(), 1u);
505 const std::string label2 = host_->label_;
506 const std::string device_id2 = host_->video_devices_.front().device.id;
507 int session_id2 = host_->video_devices_.front().session_id;
508 EXPECT_EQ(device_id1, device_id2);
509 EXPECT_EQ(session_id1, session_id2);
510 EXPECT_NE(label1, label2);
513 TEST_F(MediaStreamDispatcherHostTest,
514 GenerateStreamAndOpenDeviceFromSameRenderId) {
515 StreamOptions options(false, true);
517 // Generate first stream.
518 SetupFakeUI(true);
519 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
521 EXPECT_EQ(host_->audio_devices_.size(), 0u);
522 EXPECT_EQ(host_->video_devices_.size(), 1u);
523 const std::string label1 = host_->label_;
524 const std::string device_id1 = host_->video_devices_.front().device.id;
525 const int session_id1 = host_->video_devices_.front().session_id;
527 // Generate second stream.
528 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
530 const std::string device_id2 = host_->opened_device_.device.id;
531 const int session_id2 = host_->opened_device_.session_id;
532 const std::string label2 = host_->label_;
534 EXPECT_EQ(device_id1, device_id2);
535 EXPECT_NE(session_id1, session_id2);
536 EXPECT_NE(label1, label2);
540 // This test generates two streams with video only using two separate render
541 // frame ids. The same device id but different session ids are expected.
542 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
543 StreamOptions options(false, true);
545 // Generate first stream.
546 SetupFakeUI(true);
547 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
549 // Check the latest generated stream.
550 EXPECT_EQ(host_->audio_devices_.size(), 0u);
551 EXPECT_EQ(host_->video_devices_.size(), 1u);
552 const std::string label1 = host_->label_;
553 const std::string device_id1 = host_->video_devices_.front().device.id;
554 const int session_id1 = host_->video_devices_.front().session_id;
556 // Generate second stream from another render frame.
557 SetupFakeUI(true);
558 GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
560 // Check the latest generated stream.
561 EXPECT_EQ(host_->audio_devices_.size(), 0u);
562 EXPECT_EQ(host_->video_devices_.size(), 1u);
563 const std::string label2 = host_->label_;
564 const std::string device_id2 = host_->video_devices_.front().device.id;
565 const int session_id2 = host_->video_devices_.front().session_id;
566 EXPECT_EQ(device_id1, device_id2);
567 EXPECT_NE(session_id1, session_id2);
568 EXPECT_NE(label1, label2);
571 // This test request two streams with video only without waiting for the first
572 // stream to be generated before requesting the second.
573 // The same device id and session ids are expected.
574 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
575 StreamOptions options(false, true);
577 // Generate first stream.
578 SetupFakeUI(true);
580 InSequence s;
581 EXPECT_CALL(*host_.get(),
582 OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
584 // Generate second stream.
585 EXPECT_CALL(*host_.get(),
586 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
588 base::RunLoop run_loop1;
589 base::RunLoop run_loop2;
590 host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
591 run_loop1.QuitClosure());
592 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
593 run_loop2.QuitClosure());
595 run_loop1.Run();
596 run_loop2.Run();
599 // Test that we can generate streams where a mandatory sourceId is specified in
600 // the request.
601 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
602 ASSERT_GE(physical_audio_devices_.size(), 1u);
603 ASSERT_GE(physical_video_devices_.size(), 1u);
605 media::AudioDeviceNames::const_iterator audio_it =
606 physical_audio_devices_.begin();
607 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
608 std::string source_id = content::GetHMACForMediaDeviceID(
609 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
610 origin_,
611 audio_it->unique_id);
612 ASSERT_FALSE(source_id.empty());
613 StreamOptions options(true, true);
614 AddSourceIdConstraint(source_id, &options.mandatory_audio);
616 SetupFakeUI(true);
617 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
618 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
621 media::VideoCaptureDevice::Names::const_iterator video_it =
622 physical_video_devices_.begin();
623 for (; video_it != physical_video_devices_.end(); ++video_it) {
624 std::string source_id = content::GetHMACForMediaDeviceID(
625 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
626 origin_,
627 video_it->id());
628 ASSERT_FALSE(source_id.empty());
629 StreamOptions options(true, true);
630 AddSourceIdConstraint(source_id, &options.mandatory_video);
632 SetupFakeUI(true);
633 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
634 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
638 // Test that we can generate streams where a optional sourceId is specified in
639 // the request.
640 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
641 ASSERT_GE(physical_audio_devices_.size(), 1u);
642 ASSERT_GE(physical_video_devices_.size(), 1u);
644 media::AudioDeviceNames::const_iterator audio_it =
645 physical_audio_devices_.begin();
646 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
647 std::string source_id = content::GetHMACForMediaDeviceID(
648 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
649 origin_,
650 audio_it->unique_id);
651 ASSERT_FALSE(source_id.empty());
652 StreamOptions options(true, true);
653 AddSourceIdConstraint(source_id, &options.optional_audio);
655 SetupFakeUI(true);
656 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
657 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
660 media::VideoCaptureDevice::Names::const_iterator video_it =
661 physical_video_devices_.begin();
662 for (; video_it != physical_video_devices_.end(); ++video_it) {
663 std::string source_id = content::GetHMACForMediaDeviceID(
664 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
665 origin_,
666 video_it->id());
667 ASSERT_FALSE(source_id.empty());
668 StreamOptions options(true, true);
669 AddSourceIdConstraint(source_id, &options.optional_video);
671 SetupFakeUI(true);
672 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
673 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
677 // Test that generating a stream with an invalid mandatory video source id fail.
678 TEST_F(MediaStreamDispatcherHostTest,
679 GenerateStreamsWithInvalidMandatoryVideoSourceId) {
680 StreamOptions options(true, true);
681 AddSourceIdConstraint("invalid source id", &options.mandatory_video);
683 GenerateStreamAndWaitForFailure(
684 kRenderId,
685 kPageRequestId,
686 options,
687 MEDIA_DEVICE_NO_HARDWARE);
690 // Test that generating a stream with an invalid mandatory audio source id fail.
691 TEST_F(MediaStreamDispatcherHostTest,
692 GenerateStreamsWithInvalidMandatoryAudioSourceId) {
693 StreamOptions options(true, true);
694 AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
696 GenerateStreamAndWaitForFailure(
697 kRenderId,
698 kPageRequestId,
699 options,
700 MEDIA_DEVICE_NO_HARDWARE);
703 // Test that generating a stream with an invalid optional video source id
704 // succeed.
705 TEST_F(MediaStreamDispatcherHostTest,
706 GenerateStreamsWithInvalidOptionalVideoSourceId) {
707 StreamOptions options(true, true);
708 AddSourceIdConstraint("invalid source id", &options.optional_video);
710 SetupFakeUI(true);
711 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
714 // Test that generating a stream with an invalid optional audio source id
715 // succeed.
716 TEST_F(MediaStreamDispatcherHostTest,
717 GenerateStreamsWithInvalidOptionalAudioSourceId) {
718 StreamOptions options(true, true);
719 AddSourceIdConstraint("invalid source id", &options.optional_audio);
721 SetupFakeUI(true);
722 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
725 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
726 physical_video_devices_.clear();
727 video_capture_device_factory_->set_number_of_devices(0);
728 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
729 StreamOptions options(true, true);
731 SetupFakeUI(false);
732 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
733 MEDIA_DEVICE_NO_HARDWARE);
736 // Test that if a OnStopStreamDevice message is received for a device that has
737 // been opened in a MediaStream and by pepper, the device is only stopped for
738 // the MediaStream.
739 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
740 StreamOptions options(false, true);
742 SetupFakeUI(true);
743 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
745 std::string stream_request_label = host_->label_;
746 StreamDeviceInfo video_device_info = host_->video_devices_.front();
747 ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
748 stream_request_label).size());
750 // Open the same device by Pepper.
751 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
752 video_device_info.device.id);
753 std::string open_device_request_label = host_->label_;
755 // Stop the device in the MediaStream.
756 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
758 EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
759 stream_request_label).size());
760 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
761 open_device_request_label).size());
764 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
765 StreamOptions options(true, true);
767 SetupFakeUI(true);
768 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
770 std::string request_label1 = host_->label_;
771 StreamDeviceInfo video_device_info = host_->video_devices_.front();
772 // Expect that 1 audio and 1 video device has been opened.
773 EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
774 request_label1).size());
776 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
777 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
778 request_label1).size());
780 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
781 std::string request_label2 = host_->label_;
783 StreamDeviceInfoArray request1_devices =
784 media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
785 StreamDeviceInfoArray request2_devices =
786 media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
788 ASSERT_EQ(1u, request1_devices.size());
789 ASSERT_EQ(2u, request2_devices.size());
791 // Test that the same audio device has been opened in both streams.
792 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
793 request2_devices[0]) ||
794 StreamDeviceInfo::IsEqual(request1_devices[0],
795 request2_devices[1]));
798 TEST_F(MediaStreamDispatcherHostTest,
799 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
800 StreamOptions options(false, true);
802 SetupFakeUI(true);
803 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
804 EXPECT_EQ(host_->video_devices_.size(), 1u);
806 // Generate a second stream.
807 EXPECT_CALL(*host_.get(),
808 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
810 base::RunLoop run_loop1;
811 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
812 run_loop1.QuitClosure());
814 // Stop the video stream device from stream 1 while waiting for the
815 // second stream to be generated.
816 host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
817 run_loop1.Run();
819 EXPECT_EQ(host_->video_devices_.size(), 1u);
822 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
823 StreamOptions options(false, true);
825 base::RunLoop run_loop;
827 // Create multiple GenerateStream requests.
828 size_t streams = 5;
829 for (size_t i = 1; i <= streams; ++i) {
830 host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
831 run_loop.QuitClosure());
834 // Calling OnChannelClosing() to cancel all the pending requests.
835 host_->OnChannelClosing();
836 run_loop.RunUntilIdle();
839 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
840 StreamOptions options(false, true);
842 // Create first group of streams.
843 size_t generated_streams = 3;
844 for (size_t i = 0; i < generated_streams; ++i) {
845 SetupFakeUI(true);
846 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
849 // Calling OnChannelClosing() to cancel all the pending/generated streams.
850 host_->OnChannelClosing();
851 base::RunLoop().RunUntilIdle();
854 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
855 StreamOptions options(false, true);
857 base::Closure close_callback;
858 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
859 EXPECT_CALL(*stream_ui, OnStarted(_, _))
860 .WillOnce(SaveArg<0>(&close_callback));
861 media_stream_manager_->UseFakeUI(stream_ui.Pass());
863 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
865 EXPECT_EQ(host_->audio_devices_.size(), 0u);
866 EXPECT_EQ(host_->video_devices_.size(), 1u);
868 ASSERT_FALSE(close_callback.is_null());
869 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
870 close_callback.Run();
871 base::RunLoop().RunUntilIdle();
874 // Test that the dispatcher is notified if a video device that is in use is
875 // being unplugged.
876 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
877 StreamOptions options(true, true);
878 SetupFakeUI(true);
879 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
880 EXPECT_EQ(host_->audio_devices_.size(), 1u);
881 EXPECT_EQ(host_->video_devices_.size(), 1u);
883 video_capture_device_factory_->set_number_of_devices(0);
885 base::RunLoop run_loop;
886 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
887 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
888 media_stream_manager_->OnDevicesChanged(
889 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
891 run_loop.Run();
894 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
895 SetupFakeUI(false);
896 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
897 MEDIA_DEVICE_AUDIO_CAPTURE);
898 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
901 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
902 SetupFakeUI(false);
903 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
904 MEDIA_DEVICE_VIDEO_CAPTURE);
905 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
908 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevicesNoAccess) {
909 SetupFakeUI(false);
910 stream_ui_->SetMicAccess(false);
911 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
912 MEDIA_DEVICE_AUDIO_CAPTURE);
913 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
916 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevicesNoAccess) {
917 SetupFakeUI(false);
918 stream_ui_->SetCameraAccess(false);
919 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
920 MEDIA_DEVICE_VIDEO_CAPTURE);
921 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
924 }; // namespace content