Use multiline attribute to check for IA2_STATE_MULTILINE.
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_dispatcher_host_unittest.cc
blob9b3d22f26613f51d3421383bee264469c56b3aa4
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_);
237 #if defined(OS_WIN)
238 // Override the Video Capture Thread that MediaStreamManager constructs.
239 media_stream_manager_->video_capture_manager()->set_device_task_runner(
240 base::MessageLoopProxy::current());
241 #endif
243 MockResourceContext* mock_resource_context =
244 static_cast<MockResourceContext*>(
245 browser_context_.GetResourceContext());
247 host_ = new MockMediaStreamDispatcherHost(
248 mock_resource_context->GetMediaDeviceIDSalt(),
249 base::MessageLoopProxy::current(),
250 media_stream_manager_.get());
252 // Use the fake content client and browser.
253 content_client_.reset(new TestContentClient());
254 SetContentClient(content_client_.get());
255 old_browser_client_ = SetBrowserClientForTesting(host_.get());
257 #if defined(OS_CHROMEOS)
258 chromeos::CrasAudioHandler::InitializeForTesting();
259 #endif
262 ~MediaStreamDispatcherHostTest() override {
263 #if defined(OS_CHROMEOS)
264 chromeos::CrasAudioHandler::Shutdown();
265 #endif
268 void SetUp() override {
269 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
270 ASSERT_GT(physical_video_devices_.size(), 0u);
272 media_stream_manager_->audio_input_device_manager()->GetFakeDeviceNames(
273 &physical_audio_devices_);
274 ASSERT_GT(physical_audio_devices_.size(), 0u);
277 void TearDown() override { host_->OnChannelClosing(); }
279 protected:
280 virtual void SetupFakeUI(bool expect_started) {
281 stream_ui_ = new MockMediaStreamUIProxy();
282 if (expect_started) {
283 EXPECT_CALL(*stream_ui_, OnStarted(_, _));
285 media_stream_manager_->UseFakeUI(
286 scoped_ptr<FakeMediaStreamUIProxy>(stream_ui_));
289 void GenerateStreamAndWaitForResult(int render_frame_id,
290 int page_request_id,
291 const StreamOptions& options) {
292 base::RunLoop run_loop;
293 int expected_audio_array_size =
294 (options.audio_requested &&
295 physical_audio_devices_.size() > 0) ? 1 : 0;
296 int expected_video_array_size =
297 (options.video_requested &&
298 physical_video_devices_.size() > 0) ? 1 : 0;
299 EXPECT_CALL(*host_.get(), OnStreamGenerated(render_frame_id,
300 page_request_id,
301 expected_audio_array_size,
302 expected_video_array_size));
303 host_->OnGenerateStream(render_frame_id, page_request_id, options, origin_,
304 run_loop.QuitClosure());
305 run_loop.Run();
306 EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
307 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
308 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
309 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
312 void GenerateStreamAndWaitForFailure(
313 int render_frame_id,
314 int page_request_id,
315 const StreamOptions& options,
316 MediaStreamRequestResult expected_result) {
317 base::RunLoop run_loop;
318 EXPECT_CALL(*host_.get(),
319 OnStreamGenerationFailed(render_frame_id,
320 page_request_id,
321 expected_result));
322 host_->OnGenerateStream(render_frame_id, page_request_id, options,
323 origin_, run_loop.QuitClosure());
324 run_loop.Run();
327 void OpenVideoDeviceAndWaitForResult(int render_frame_id,
328 int page_request_id,
329 const std::string& device_id) {
330 base::RunLoop run_loop;
331 host_->OnOpenDevice(render_frame_id, page_request_id, device_id,
332 MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
333 run_loop.QuitClosure());
334 run_loop.Run();
335 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
336 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
339 void EnumerateDevicesAndWaitForResult(int render_frame_id,
340 int page_request_id,
341 MediaStreamType type) {
342 base::RunLoop run_loop;
343 host_->OnEnumerateDevices(render_frame_id, page_request_id, type, origin_,
344 run_loop.QuitClosure());
345 run_loop.Run();
346 ASSERT_FALSE(host_->enumerated_devices_.empty());
347 EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
348 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
351 bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
352 for (size_t i = 0; i < devices.size(); ++i) {
353 media::AudioDeviceNames::const_iterator audio_it =
354 physical_audio_devices_.begin();
355 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
356 if (audio_it->unique_id == devices[i].device.id)
357 return true;
359 media::VideoCaptureDevice::Names::const_iterator video_it =
360 physical_video_devices_.begin();
361 for (; video_it != physical_video_devices_.end(); ++video_it) {
362 if (video_it->id() == devices[i].device.id)
363 return true;
366 return false;
369 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
370 const GURL& origin) {
371 for (size_t i = 0; i < devices.size(); ++i) {
372 bool found_match = false;
373 media::AudioDeviceNames::const_iterator audio_it =
374 physical_audio_devices_.begin();
375 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
376 if (content::DoesMediaDeviceIDMatchHMAC(
377 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
378 origin,
379 devices[i].device.id,
380 audio_it->unique_id)) {
381 EXPECT_FALSE(found_match);
382 found_match = true;
385 media::VideoCaptureDevice::Names::const_iterator video_it =
386 physical_video_devices_.begin();
387 for (; video_it != physical_video_devices_.end(); ++video_it) {
388 if (content::DoesMediaDeviceIDMatchHMAC(
389 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
390 origin,
391 devices[i].device.id,
392 video_it->id())) {
393 EXPECT_FALSE(found_match);
394 found_match = true;
397 if (!found_match)
398 return false;
400 return true;
403 // Returns true if all devices have labels, false otherwise.
404 bool DoesContainLabels(const StreamDeviceInfoArray& devices) {
405 for (size_t i = 0; i < devices.size(); ++i) {
406 if (devices[i].device.name.empty())
407 return false;
409 return true;
412 // Returns true if no devices have labels, false otherwise.
413 bool DoesNotContainLabels(const StreamDeviceInfoArray& devices) {
414 for (size_t i = 0; i < devices.size(); ++i) {
415 if (!devices[i].device.name.empty())
416 return false;
418 return true;
421 void AddSourceIdConstraint(const std::string& source_id,
422 StreamOptions::Constraints* constraints) {
423 constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
424 source_id));
427 scoped_refptr<MockMediaStreamDispatcherHost> host_;
428 scoped_ptr<media::AudioManager> audio_manager_;
429 scoped_ptr<MediaStreamManager> media_stream_manager_;
430 MockMediaStreamUIProxy* stream_ui_;
431 ContentBrowserClient* old_browser_client_;
432 scoped_ptr<ContentClient> content_client_;
433 content::TestBrowserThreadBundle thread_bundle_;
434 content::TestBrowserContext browser_context_;
435 media::AudioDeviceNames physical_audio_devices_;
436 media::VideoCaptureDevice::Names physical_video_devices_;
437 GURL origin_;
438 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
441 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
442 StreamOptions options(false, true);
444 SetupFakeUI(true);
445 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
447 EXPECT_EQ(host_->audio_devices_.size(), 0u);
448 EXPECT_EQ(host_->video_devices_.size(), 1u);
451 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
452 StreamOptions options(true, false);
454 SetupFakeUI(true);
455 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
457 EXPECT_EQ(host_->audio_devices_.size(), 1u);
458 EXPECT_EQ(host_->video_devices_.size(), 0u);
461 // This test simulates a shutdown scenario: we don't setup a fake UI proxy for
462 // MediaStreamManager, so it will create an ordinary one which will not find
463 // a RenderFrameHostDelegate. This normally should only be the case at shutdown.
464 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
465 StreamOptions options(false, false);
467 GenerateStreamAndWaitForFailure(
468 kRenderId,
469 kPageRequestId,
470 options,
471 MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN);
474 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
475 StreamOptions options(true, true);
477 SetupFakeUI(true);
478 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
480 EXPECT_EQ(host_->audio_devices_.size(), 1u);
481 EXPECT_EQ(host_->video_devices_.size(), 1u);
484 // This test generates two streams with video only using the same render frame
485 // id. The same capture device with the same device and session id is expected
486 // to be used.
487 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
488 StreamOptions options(false, true);
490 // Generate first stream.
491 SetupFakeUI(true);
492 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, 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 label1 = host_->label_;
498 const std::string device_id1 = host_->video_devices_.front().device.id;
499 const int session_id1 = host_->video_devices_.front().session_id;
501 // Generate second stream.
502 SetupFakeUI(true);
503 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
505 // Check the latest generated stream.
506 EXPECT_EQ(host_->audio_devices_.size(), 0u);
507 EXPECT_EQ(host_->video_devices_.size(), 1u);
508 const std::string label2 = host_->label_;
509 const std::string device_id2 = host_->video_devices_.front().device.id;
510 int session_id2 = host_->video_devices_.front().session_id;
511 EXPECT_EQ(device_id1, device_id2);
512 EXPECT_EQ(session_id1, session_id2);
513 EXPECT_NE(label1, label2);
516 TEST_F(MediaStreamDispatcherHostTest,
517 GenerateStreamAndOpenDeviceFromSameRenderId) {
518 StreamOptions options(false, true);
520 // Generate first stream.
521 SetupFakeUI(true);
522 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
524 EXPECT_EQ(host_->audio_devices_.size(), 0u);
525 EXPECT_EQ(host_->video_devices_.size(), 1u);
526 const std::string label1 = host_->label_;
527 const std::string device_id1 = host_->video_devices_.front().device.id;
528 const int session_id1 = host_->video_devices_.front().session_id;
530 // Generate second stream.
531 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
533 const std::string device_id2 = host_->opened_device_.device.id;
534 const int session_id2 = host_->opened_device_.session_id;
535 const std::string label2 = host_->label_;
537 EXPECT_EQ(device_id1, device_id2);
538 EXPECT_NE(session_id1, session_id2);
539 EXPECT_NE(label1, label2);
543 // This test generates two streams with video only using two separate render
544 // frame ids. The same device id but different session ids are expected.
545 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
546 StreamOptions options(false, true);
548 // Generate first stream.
549 SetupFakeUI(true);
550 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, 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 label1 = host_->label_;
556 const std::string device_id1 = host_->video_devices_.front().device.id;
557 const int session_id1 = host_->video_devices_.front().session_id;
559 // Generate second stream from another render frame.
560 SetupFakeUI(true);
561 GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
563 // Check the latest generated stream.
564 EXPECT_EQ(host_->audio_devices_.size(), 0u);
565 EXPECT_EQ(host_->video_devices_.size(), 1u);
566 const std::string label2 = host_->label_;
567 const std::string device_id2 = host_->video_devices_.front().device.id;
568 const int session_id2 = host_->video_devices_.front().session_id;
569 EXPECT_EQ(device_id1, device_id2);
570 EXPECT_NE(session_id1, session_id2);
571 EXPECT_NE(label1, label2);
574 // This test request two streams with video only without waiting for the first
575 // stream to be generated before requesting the second.
576 // The same device id and session ids are expected.
577 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
578 StreamOptions options(false, true);
580 // Generate first stream.
581 SetupFakeUI(true);
583 InSequence s;
584 EXPECT_CALL(*host_.get(),
585 OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
587 // Generate second stream.
588 EXPECT_CALL(*host_.get(),
589 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
591 base::RunLoop run_loop1;
592 base::RunLoop run_loop2;
593 host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
594 run_loop1.QuitClosure());
595 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
596 run_loop2.QuitClosure());
598 run_loop1.Run();
599 run_loop2.Run();
602 // Test that we can generate streams where a mandatory sourceId is specified in
603 // the request.
604 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
605 ASSERT_GE(physical_audio_devices_.size(), 1u);
606 ASSERT_GE(physical_video_devices_.size(), 1u);
608 media::AudioDeviceNames::const_iterator audio_it =
609 physical_audio_devices_.begin();
610 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
611 std::string source_id = content::GetHMACForMediaDeviceID(
612 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
613 origin_,
614 audio_it->unique_id);
615 ASSERT_FALSE(source_id.empty());
616 StreamOptions options(true, true);
617 AddSourceIdConstraint(source_id, &options.mandatory_audio);
619 SetupFakeUI(true);
620 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
621 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
624 media::VideoCaptureDevice::Names::const_iterator video_it =
625 physical_video_devices_.begin();
626 for (; video_it != physical_video_devices_.end(); ++video_it) {
627 std::string source_id = content::GetHMACForMediaDeviceID(
628 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
629 origin_,
630 video_it->id());
631 ASSERT_FALSE(source_id.empty());
632 StreamOptions options(true, true);
633 AddSourceIdConstraint(source_id, &options.mandatory_video);
635 SetupFakeUI(true);
636 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
637 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
641 // Test that we can generate streams where a optional sourceId is specified in
642 // the request.
643 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
644 ASSERT_GE(physical_audio_devices_.size(), 1u);
645 ASSERT_GE(physical_video_devices_.size(), 1u);
647 media::AudioDeviceNames::const_iterator audio_it =
648 physical_audio_devices_.begin();
649 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
650 std::string source_id = content::GetHMACForMediaDeviceID(
651 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
652 origin_,
653 audio_it->unique_id);
654 ASSERT_FALSE(source_id.empty());
655 StreamOptions options(true, true);
656 AddSourceIdConstraint(source_id, &options.optional_audio);
658 SetupFakeUI(true);
659 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
660 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
663 media::VideoCaptureDevice::Names::const_iterator video_it =
664 physical_video_devices_.begin();
665 for (; video_it != physical_video_devices_.end(); ++video_it) {
666 std::string source_id = content::GetHMACForMediaDeviceID(
667 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
668 origin_,
669 video_it->id());
670 ASSERT_FALSE(source_id.empty());
671 StreamOptions options(true, true);
672 AddSourceIdConstraint(source_id, &options.optional_video);
674 SetupFakeUI(true);
675 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
676 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
680 // Test that generating a stream with an invalid mandatory video source id fail.
681 TEST_F(MediaStreamDispatcherHostTest,
682 GenerateStreamsWithInvalidMandatoryVideoSourceId) {
683 StreamOptions options(true, true);
684 AddSourceIdConstraint("invalid source id", &options.mandatory_video);
686 GenerateStreamAndWaitForFailure(
687 kRenderId,
688 kPageRequestId,
689 options,
690 MEDIA_DEVICE_NO_HARDWARE);
693 // Test that generating a stream with an invalid mandatory audio source id fail.
694 TEST_F(MediaStreamDispatcherHostTest,
695 GenerateStreamsWithInvalidMandatoryAudioSourceId) {
696 StreamOptions options(true, true);
697 AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
699 GenerateStreamAndWaitForFailure(
700 kRenderId,
701 kPageRequestId,
702 options,
703 MEDIA_DEVICE_NO_HARDWARE);
706 // Test that generating a stream with an invalid optional video source id
707 // succeed.
708 TEST_F(MediaStreamDispatcherHostTest,
709 GenerateStreamsWithInvalidOptionalVideoSourceId) {
710 StreamOptions options(true, true);
711 AddSourceIdConstraint("invalid source id", &options.optional_video);
713 SetupFakeUI(true);
714 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
717 // Test that generating a stream with an invalid optional audio source id
718 // succeed.
719 TEST_F(MediaStreamDispatcherHostTest,
720 GenerateStreamsWithInvalidOptionalAudioSourceId) {
721 StreamOptions options(true, true);
722 AddSourceIdConstraint("invalid source id", &options.optional_audio);
724 SetupFakeUI(true);
725 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
728 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
729 physical_video_devices_.clear();
730 video_capture_device_factory_->set_number_of_devices(0);
731 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
732 StreamOptions options(true, true);
734 SetupFakeUI(false);
735 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
736 MEDIA_DEVICE_NO_HARDWARE);
739 // Test that if a OnStopStreamDevice message is received for a device that has
740 // been opened in a MediaStream and by pepper, the device is only stopped for
741 // the MediaStream.
742 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
743 StreamOptions options(false, true);
745 SetupFakeUI(true);
746 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
748 std::string stream_request_label = host_->label_;
749 StreamDeviceInfo video_device_info = host_->video_devices_.front();
750 ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
751 stream_request_label).size());
753 // Open the same device by Pepper.
754 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
755 video_device_info.device.id);
756 std::string open_device_request_label = host_->label_;
758 // Stop the device in the MediaStream.
759 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
761 EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
762 stream_request_label).size());
763 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
764 open_device_request_label).size());
767 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
768 StreamOptions options(true, true);
770 SetupFakeUI(true);
771 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
773 std::string request_label1 = host_->label_;
774 StreamDeviceInfo video_device_info = host_->video_devices_.front();
775 // Expect that 1 audio and 1 video device has been opened.
776 EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
777 request_label1).size());
779 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
780 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
781 request_label1).size());
783 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
784 std::string request_label2 = host_->label_;
786 StreamDeviceInfoArray request1_devices =
787 media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
788 StreamDeviceInfoArray request2_devices =
789 media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
791 ASSERT_EQ(1u, request1_devices.size());
792 ASSERT_EQ(2u, request2_devices.size());
794 // Test that the same audio device has been opened in both streams.
795 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
796 request2_devices[0]) ||
797 StreamDeviceInfo::IsEqual(request1_devices[0],
798 request2_devices[1]));
801 TEST_F(MediaStreamDispatcherHostTest,
802 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
803 StreamOptions options(false, true);
805 SetupFakeUI(true);
806 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
807 EXPECT_EQ(host_->video_devices_.size(), 1u);
809 // Generate a second stream.
810 EXPECT_CALL(*host_.get(),
811 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
813 base::RunLoop run_loop1;
814 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
815 run_loop1.QuitClosure());
817 // Stop the video stream device from stream 1 while waiting for the
818 // second stream to be generated.
819 host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
820 run_loop1.Run();
822 EXPECT_EQ(host_->video_devices_.size(), 1u);
825 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
826 StreamOptions options(false, true);
828 base::RunLoop run_loop;
830 // Create multiple GenerateStream requests.
831 size_t streams = 5;
832 for (size_t i = 1; i <= streams; ++i) {
833 host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
834 run_loop.QuitClosure());
837 // Calling OnChannelClosing() to cancel all the pending requests.
838 host_->OnChannelClosing();
839 run_loop.RunUntilIdle();
842 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
843 StreamOptions options(false, true);
845 // Create first group of streams.
846 size_t generated_streams = 3;
847 for (size_t i = 0; i < generated_streams; ++i) {
848 SetupFakeUI(true);
849 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
852 // Calling OnChannelClosing() to cancel all the pending/generated streams.
853 host_->OnChannelClosing();
854 base::RunLoop().RunUntilIdle();
857 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
858 StreamOptions options(false, true);
860 base::Closure close_callback;
861 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
862 EXPECT_CALL(*stream_ui, OnStarted(_, _))
863 .WillOnce(SaveArg<0>(&close_callback));
864 media_stream_manager_->UseFakeUI(stream_ui.Pass());
866 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
868 EXPECT_EQ(host_->audio_devices_.size(), 0u);
869 EXPECT_EQ(host_->video_devices_.size(), 1u);
871 ASSERT_FALSE(close_callback.is_null());
872 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
873 close_callback.Run();
874 base::RunLoop().RunUntilIdle();
877 // Test that the dispatcher is notified if a video device that is in use is
878 // being unplugged.
879 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
880 StreamOptions options(true, true);
881 SetupFakeUI(true);
882 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
883 EXPECT_EQ(host_->audio_devices_.size(), 1u);
884 EXPECT_EQ(host_->video_devices_.size(), 1u);
886 video_capture_device_factory_->set_number_of_devices(0);
888 base::RunLoop run_loop;
889 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
890 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
891 media_stream_manager_->OnDevicesChanged(
892 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
894 run_loop.Run();
897 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
898 SetupFakeUI(false);
899 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
900 MEDIA_DEVICE_AUDIO_CAPTURE);
901 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
904 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
905 SetupFakeUI(false);
906 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
907 MEDIA_DEVICE_VIDEO_CAPTURE);
908 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
911 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevicesNoAccess) {
912 SetupFakeUI(false);
913 stream_ui_->SetMicAccess(false);
914 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
915 MEDIA_DEVICE_AUDIO_CAPTURE);
916 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
919 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevicesNoAccess) {
920 SetupFakeUI(false);
921 stream_ui_->SetCameraAccess(false);
922 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
923 MEDIA_DEVICE_VIDEO_CAPTURE);
924 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
927 }; // namespace content