Add ICU message format support
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_dispatcher_host_unittest.cc
blobf8f4faef8bb2a50e7098684b4dbde97b7cd58b63
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 <queue>
6 #include <string>
8 #include "base/bind.h"
9 #include "base/callback_helpers.h"
10 #include "base/command_line.h"
11 #include "base/location.h"
12 #include "base/run_loop.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/thread_task_runner_handle.h"
15 #include "content/browser/browser_thread_impl.h"
16 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
17 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
18 #include "content/browser/renderer_host/media/media_stream_manager.h"
19 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
20 #include "content/browser/renderer_host/media/video_capture_manager.h"
21 #include "content/common/media/media_stream_messages.h"
22 #include "content/common/media/media_stream_options.h"
23 #include "content/public/browser/media_device_id.h"
24 #include "content/public/common/content_switches.h"
25 #include "content/public/test/mock_resource_context.h"
26 #include "content/public/test/test_browser_context.h"
27 #include "content/public/test/test_browser_thread_bundle.h"
28 #include "content/test/test_content_browser_client.h"
29 #include "content/test/test_content_client.h"
30 #include "ipc/ipc_message_macros.h"
31 #include "media/audio/mock_audio_manager.h"
32 #include "media/base/media_switches.h"
33 #include "media/capture/video/fake_video_capture_device_factory.h"
34 #include "net/url_request/url_request_context.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
38 #if defined(OS_CHROMEOS)
39 #include "chromeos/audio/cras_audio_handler.h"
40 #endif
42 using ::testing::_;
43 using ::testing::DeleteArg;
44 using ::testing::DoAll;
45 using ::testing::InSequence;
46 using ::testing::Return;
47 using ::testing::SaveArg;
49 const int kProcessId = 5;
50 const int kRenderId = 6;
51 const int kPageRequestId = 7;
53 namespace content {
55 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
56 public TestContentBrowserClient {
57 public:
58 MockMediaStreamDispatcherHost(
59 const ResourceContext::SaltCallback salt_callback,
60 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
61 MediaStreamManager* manager)
62 : MediaStreamDispatcherHost(kProcessId, salt_callback, manager),
63 task_runner_(task_runner),
64 current_ipc_(NULL) {}
66 // A list of mock methods.
67 MOCK_METHOD4(OnStreamGenerated,
68 void(int routing_id, int request_id, int audio_array_size,
69 int video_array_size));
70 MOCK_METHOD3(OnStreamGenerationFailed, void(int routing_id,
71 int request_id,
72 MediaStreamRequestResult result));
73 MOCK_METHOD1(OnDeviceStopped, void(int routing_id));
74 MOCK_METHOD2(OnDeviceOpened, void(int routing_id, int request_id));
76 // Accessor to private functions.
77 void OnGenerateStream(int render_frame_id,
78 int page_request_id,
79 const StreamOptions& components,
80 const GURL& security_origin,
81 const base::Closure& quit_closure) {
82 quit_closures_.push(quit_closure);
83 MediaStreamDispatcherHost::OnGenerateStream(
84 render_frame_id, page_request_id, components, security_origin, false);
87 void OnStopStreamDevice(int render_frame_id,
88 const std::string& device_id) {
89 MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id, device_id);
92 void OnOpenDevice(int render_frame_id,
93 int page_request_id,
94 const std::string& device_id,
95 MediaStreamType type,
96 const GURL& security_origin,
97 const base::Closure& quit_closure) {
98 quit_closures_.push(quit_closure);
99 MediaStreamDispatcherHost::OnOpenDevice(
100 render_frame_id, page_request_id, device_id, type, security_origin);
103 void OnEnumerateDevices(int render_frame_id,
104 int page_request_id,
105 MediaStreamType type,
106 const GURL& security_origin,
107 const base::Closure& quit_closure) {
108 quit_closures_.push(quit_closure);
109 MediaStreamDispatcherHost::OnEnumerateDevices(
110 render_frame_id, page_request_id, type, security_origin);
113 std::string label_;
114 StreamDeviceInfoArray audio_devices_;
115 StreamDeviceInfoArray video_devices_;
116 StreamDeviceInfo opened_device_;
117 StreamDeviceInfoArray enumerated_devices_;
119 private:
120 ~MockMediaStreamDispatcherHost() override {}
122 // This method is used to dispatch IPC messages to the renderer. We intercept
123 // these messages here and dispatch to our mock methods to verify the
124 // conversation between this object and the renderer.
125 bool Send(IPC::Message* message) override {
126 CHECK(message);
127 current_ipc_ = message;
129 // In this method we dispatch the messages to the according handlers as if
130 // we are the renderer.
131 bool handled = true;
132 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message)
133 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated,
134 OnStreamGeneratedInternal)
135 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed,
136 OnStreamGenerationFailedInternal)
137 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped, OnDeviceStoppedInternal)
138 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened, OnDeviceOpenedInternal)
139 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated, OnDevicesEnumerated)
140 IPC_MESSAGE_UNHANDLED(handled = false)
141 IPC_END_MESSAGE_MAP()
142 EXPECT_TRUE(handled);
144 delete message;
145 current_ipc_ = NULL;
146 return true;
149 // These handler methods do minimal things and delegate to the mock methods.
150 void OnStreamGeneratedInternal(
151 int request_id,
152 std::string label,
153 StreamDeviceInfoArray audio_device_list,
154 StreamDeviceInfoArray video_device_list) {
155 OnStreamGenerated(current_ipc_->routing_id(), request_id,
156 audio_device_list.size(), video_device_list.size());
157 // Notify that the event have occurred.
158 base::Closure quit_closure = quit_closures_.front();
159 quit_closures_.pop();
160 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
162 label_ = label;
163 audio_devices_ = audio_device_list;
164 video_devices_ = video_device_list;
167 void OnStreamGenerationFailedInternal(
168 int request_id,
169 content::MediaStreamRequestResult result) {
170 OnStreamGenerationFailed(current_ipc_->routing_id(), request_id, result);
171 if (!quit_closures_.empty()) {
172 base::Closure quit_closure = quit_closures_.front();
173 quit_closures_.pop();
174 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
177 label_= "";
180 void OnDeviceStoppedInternal(const std::string& label,
181 const content::StreamDeviceInfo& device) {
182 if (IsVideoMediaType(device.device.type))
183 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, video_devices_[0]));
184 if (IsAudioInputMediaType(device.device.type))
185 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, audio_devices_[0]));
187 OnDeviceStopped(current_ipc_->routing_id());
190 void OnDeviceOpenedInternal(int request_id,
191 const std::string& label,
192 const StreamDeviceInfo& device) {
193 base::Closure quit_closure = quit_closures_.front();
194 quit_closures_.pop();
195 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
196 label_ = label;
197 opened_device_ = device;
200 void OnDevicesEnumerated(int request_id,
201 const StreamDeviceInfoArray& devices) {
202 base::Closure quit_closure = quit_closures_.front();
203 quit_closures_.pop();
204 task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
205 enumerated_devices_ = devices;
208 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
209 IPC::Message* current_ipc_;
210 std::queue<base::Closure> quit_closures_;
213 class MockMediaStreamUIProxy : public FakeMediaStreamUIProxy {
214 public:
215 MOCK_METHOD2(
216 OnStarted,
217 void(const base::Closure& stop,
218 const MediaStreamUIProxy::WindowIdCallback& window_id_callback));
221 class MediaStreamDispatcherHostTest : public testing::Test {
222 public:
223 MediaStreamDispatcherHostTest()
224 : old_browser_client_(NULL),
225 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
226 origin_("https://test.com") {
227 audio_manager_.reset(
228 new media::MockAudioManager(base::ThreadTaskRunnerHandle::Get()));
229 // Make sure we use fake devices to avoid long delays.
230 base::CommandLine::ForCurrentProcess()->AppendSwitch(
231 switches::kUseFakeDeviceForMediaStream);
232 // Create our own MediaStreamManager.
233 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
234 video_capture_device_factory_ =
235 static_cast<media::FakeVideoCaptureDeviceFactory*>(
236 media_stream_manager_->video_capture_manager()
237 ->video_capture_device_factory());
238 DCHECK(video_capture_device_factory_);
239 #if defined(OS_WIN)
240 // Override the Video Capture Thread that MediaStreamManager constructs.
241 media_stream_manager_->video_capture_manager()->set_device_task_runner(
242 base::ThreadTaskRunnerHandle::Get());
243 #endif
245 MockResourceContext* mock_resource_context =
246 static_cast<MockResourceContext*>(
247 browser_context_.GetResourceContext());
249 host_ = new MockMediaStreamDispatcherHost(
250 mock_resource_context->GetMediaDeviceIDSalt(),
251 base::ThreadTaskRunnerHandle::Get(), media_stream_manager_.get());
253 // Use the fake content client and browser.
254 content_client_.reset(new TestContentClient());
255 SetContentClient(content_client_.get());
256 old_browser_client_ = SetBrowserClientForTesting(host_.get());
258 #if defined(OS_CHROMEOS)
259 chromeos::CrasAudioHandler::InitializeForTesting();
260 #endif
263 ~MediaStreamDispatcherHostTest() override {
264 #if defined(OS_CHROMEOS)
265 chromeos::CrasAudioHandler::Shutdown();
266 #endif
269 void SetUp() override {
270 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
271 ASSERT_GT(physical_video_devices_.size(), 0u);
273 media_stream_manager_->audio_input_device_manager()->GetFakeDeviceNames(
274 &physical_audio_devices_);
275 ASSERT_GT(physical_audio_devices_.size(), 0u);
278 void TearDown() override { host_->OnChannelClosing(); }
280 protected:
281 virtual void SetupFakeUI(bool expect_started) {
282 stream_ui_ = new MockMediaStreamUIProxy();
283 if (expect_started) {
284 EXPECT_CALL(*stream_ui_, OnStarted(_, _));
286 media_stream_manager_->UseFakeUI(
287 scoped_ptr<FakeMediaStreamUIProxy>(stream_ui_));
290 void GenerateStreamAndWaitForResult(int render_frame_id,
291 int page_request_id,
292 const StreamOptions& options) {
293 base::RunLoop run_loop;
294 int expected_audio_array_size =
295 (options.audio_requested &&
296 physical_audio_devices_.size() > 0) ? 1 : 0;
297 int expected_video_array_size =
298 (options.video_requested &&
299 physical_video_devices_.size() > 0) ? 1 : 0;
300 EXPECT_CALL(*host_.get(), OnStreamGenerated(render_frame_id,
301 page_request_id,
302 expected_audio_array_size,
303 expected_video_array_size));
304 host_->OnGenerateStream(render_frame_id, page_request_id, options, origin_,
305 run_loop.QuitClosure());
306 run_loop.Run();
307 EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
308 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
309 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
310 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
313 void GenerateStreamAndWaitForFailure(
314 int render_frame_id,
315 int page_request_id,
316 const StreamOptions& options,
317 MediaStreamRequestResult expected_result) {
318 base::RunLoop run_loop;
319 EXPECT_CALL(*host_.get(),
320 OnStreamGenerationFailed(render_frame_id,
321 page_request_id,
322 expected_result));
323 host_->OnGenerateStream(render_frame_id, page_request_id, options,
324 origin_, run_loop.QuitClosure());
325 run_loop.Run();
328 void OpenVideoDeviceAndWaitForResult(int render_frame_id,
329 int page_request_id,
330 const std::string& device_id) {
331 base::RunLoop run_loop;
332 host_->OnOpenDevice(render_frame_id, page_request_id, device_id,
333 MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
334 run_loop.QuitClosure());
335 run_loop.Run();
336 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
337 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
340 void EnumerateDevicesAndWaitForResult(int render_frame_id,
341 int page_request_id,
342 MediaStreamType type) {
343 base::RunLoop run_loop;
344 host_->OnEnumerateDevices(render_frame_id, page_request_id, type, origin_,
345 run_loop.QuitClosure());
346 run_loop.Run();
347 ASSERT_FALSE(host_->enumerated_devices_.empty());
348 EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
349 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
352 bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
353 for (size_t i = 0; i < devices.size(); ++i) {
354 media::AudioDeviceNames::const_iterator audio_it =
355 physical_audio_devices_.begin();
356 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
357 if (audio_it->unique_id == devices[i].device.id)
358 return true;
360 media::VideoCaptureDevice::Names::const_iterator video_it =
361 physical_video_devices_.begin();
362 for (; video_it != physical_video_devices_.end(); ++video_it) {
363 if (video_it->id() == devices[i].device.id)
364 return true;
367 return false;
370 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
371 const GURL& origin) {
372 for (size_t i = 0; i < devices.size(); ++i) {
373 bool found_match = false;
374 media::AudioDeviceNames::const_iterator audio_it =
375 physical_audio_devices_.begin();
376 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
377 if (content::DoesMediaDeviceIDMatchHMAC(
378 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
379 origin,
380 devices[i].device.id,
381 audio_it->unique_id)) {
382 EXPECT_FALSE(found_match);
383 found_match = true;
386 media::VideoCaptureDevice::Names::const_iterator video_it =
387 physical_video_devices_.begin();
388 for (; video_it != physical_video_devices_.end(); ++video_it) {
389 if (content::DoesMediaDeviceIDMatchHMAC(
390 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
391 origin,
392 devices[i].device.id,
393 video_it->id())) {
394 EXPECT_FALSE(found_match);
395 found_match = true;
398 if (!found_match)
399 return false;
401 return true;
404 // Returns true if all devices have labels, false otherwise.
405 bool DoesContainLabels(const StreamDeviceInfoArray& devices) {
406 for (size_t i = 0; i < devices.size(); ++i) {
407 if (devices[i].device.name.empty())
408 return false;
410 return true;
413 // Returns true if no devices have labels, false otherwise.
414 bool DoesNotContainLabels(const StreamDeviceInfoArray& devices) {
415 for (size_t i = 0; i < devices.size(); ++i) {
416 if (!devices[i].device.name.empty())
417 return false;
419 return true;
422 void AddSourceIdConstraint(const std::string& source_id,
423 StreamOptions::Constraints* constraints) {
424 constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
425 source_id));
428 scoped_refptr<MockMediaStreamDispatcherHost> host_;
429 scoped_ptr<media::AudioManager> audio_manager_;
430 scoped_ptr<MediaStreamManager> media_stream_manager_;
431 MockMediaStreamUIProxy* stream_ui_;
432 ContentBrowserClient* old_browser_client_;
433 scoped_ptr<ContentClient> content_client_;
434 content::TestBrowserThreadBundle thread_bundle_;
435 content::TestBrowserContext browser_context_;
436 media::AudioDeviceNames physical_audio_devices_;
437 media::VideoCaptureDevice::Names physical_video_devices_;
438 GURL origin_;
439 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
442 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
443 StreamOptions options(false, true);
445 SetupFakeUI(true);
446 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
448 EXPECT_EQ(host_->audio_devices_.size(), 0u);
449 EXPECT_EQ(host_->video_devices_.size(), 1u);
452 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
453 StreamOptions options(true, false);
455 SetupFakeUI(true);
456 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
458 EXPECT_EQ(host_->audio_devices_.size(), 1u);
459 EXPECT_EQ(host_->video_devices_.size(), 0u);
462 // This test simulates a shutdown scenario: we don't setup a fake UI proxy for
463 // MediaStreamManager, so it will create an ordinary one which will not find
464 // a RenderFrameHostDelegate. This normally should only be the case at shutdown.
465 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
466 StreamOptions options(false, false);
468 GenerateStreamAndWaitForFailure(
469 kRenderId,
470 kPageRequestId,
471 options,
472 MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN);
475 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
476 StreamOptions options(true, true);
478 SetupFakeUI(true);
479 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
481 EXPECT_EQ(host_->audio_devices_.size(), 1u);
482 EXPECT_EQ(host_->video_devices_.size(), 1u);
485 // This test generates two streams with video only using the same render frame
486 // id. The same capture device with the same device and session id is expected
487 // to be used.
488 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
489 StreamOptions options(false, true);
491 // Generate first stream.
492 SetupFakeUI(true);
493 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
495 // Check the latest generated stream.
496 EXPECT_EQ(host_->audio_devices_.size(), 0u);
497 EXPECT_EQ(host_->video_devices_.size(), 1u);
498 const std::string label1 = host_->label_;
499 const std::string device_id1 = host_->video_devices_.front().device.id;
500 const int session_id1 = host_->video_devices_.front().session_id;
502 // Generate second stream.
503 SetupFakeUI(true);
504 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
506 // Check the latest generated stream.
507 EXPECT_EQ(host_->audio_devices_.size(), 0u);
508 EXPECT_EQ(host_->video_devices_.size(), 1u);
509 const std::string label2 = host_->label_;
510 const std::string device_id2 = host_->video_devices_.front().device.id;
511 int session_id2 = host_->video_devices_.front().session_id;
512 EXPECT_EQ(device_id1, device_id2);
513 EXPECT_EQ(session_id1, session_id2);
514 EXPECT_NE(label1, label2);
517 TEST_F(MediaStreamDispatcherHostTest,
518 GenerateStreamAndOpenDeviceFromSameRenderId) {
519 StreamOptions options(false, true);
521 // Generate first stream.
522 SetupFakeUI(true);
523 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
525 EXPECT_EQ(host_->audio_devices_.size(), 0u);
526 EXPECT_EQ(host_->video_devices_.size(), 1u);
527 const std::string label1 = host_->label_;
528 const std::string device_id1 = host_->video_devices_.front().device.id;
529 const int session_id1 = host_->video_devices_.front().session_id;
531 // Generate second stream.
532 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
534 const std::string device_id2 = host_->opened_device_.device.id;
535 const int session_id2 = host_->opened_device_.session_id;
536 const std::string label2 = host_->label_;
538 EXPECT_EQ(device_id1, device_id2);
539 EXPECT_NE(session_id1, session_id2);
540 EXPECT_NE(label1, label2);
544 // This test generates two streams with video only using two separate render
545 // frame ids. The same device id but different session ids are expected.
546 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
547 StreamOptions options(false, true);
549 // Generate first stream.
550 SetupFakeUI(true);
551 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
553 // Check the latest generated stream.
554 EXPECT_EQ(host_->audio_devices_.size(), 0u);
555 EXPECT_EQ(host_->video_devices_.size(), 1u);
556 const std::string label1 = host_->label_;
557 const std::string device_id1 = host_->video_devices_.front().device.id;
558 const int session_id1 = host_->video_devices_.front().session_id;
560 // Generate second stream from another render frame.
561 SetupFakeUI(true);
562 GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
564 // Check the latest generated stream.
565 EXPECT_EQ(host_->audio_devices_.size(), 0u);
566 EXPECT_EQ(host_->video_devices_.size(), 1u);
567 const std::string label2 = host_->label_;
568 const std::string device_id2 = host_->video_devices_.front().device.id;
569 const int session_id2 = host_->video_devices_.front().session_id;
570 EXPECT_EQ(device_id1, device_id2);
571 EXPECT_NE(session_id1, session_id2);
572 EXPECT_NE(label1, label2);
575 // This test request two streams with video only without waiting for the first
576 // stream to be generated before requesting the second.
577 // The same device id and session ids are expected.
578 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
579 StreamOptions options(false, true);
581 // Generate first stream.
582 SetupFakeUI(true);
584 InSequence s;
585 EXPECT_CALL(*host_.get(),
586 OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
588 // Generate second stream.
589 EXPECT_CALL(*host_.get(),
590 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
592 base::RunLoop run_loop1;
593 base::RunLoop run_loop2;
594 host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
595 run_loop1.QuitClosure());
596 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
597 run_loop2.QuitClosure());
599 run_loop1.Run();
600 run_loop2.Run();
603 // Test that we can generate streams where a mandatory sourceId is specified in
604 // the request.
605 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
606 ASSERT_GE(physical_audio_devices_.size(), 1u);
607 ASSERT_GE(physical_video_devices_.size(), 1u);
609 media::AudioDeviceNames::const_iterator audio_it =
610 physical_audio_devices_.begin();
611 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
612 std::string source_id = content::GetHMACForMediaDeviceID(
613 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
614 origin_,
615 audio_it->unique_id);
616 ASSERT_FALSE(source_id.empty());
617 StreamOptions options(true, true);
618 AddSourceIdConstraint(source_id, &options.mandatory_audio);
620 SetupFakeUI(true);
621 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
622 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
625 media::VideoCaptureDevice::Names::const_iterator video_it =
626 physical_video_devices_.begin();
627 for (; video_it != physical_video_devices_.end(); ++video_it) {
628 std::string source_id = content::GetHMACForMediaDeviceID(
629 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
630 origin_,
631 video_it->id());
632 ASSERT_FALSE(source_id.empty());
633 StreamOptions options(true, true);
634 AddSourceIdConstraint(source_id, &options.mandatory_video);
636 SetupFakeUI(true);
637 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
638 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
642 // Test that we can generate streams where a optional sourceId is specified in
643 // the request.
644 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
645 ASSERT_GE(physical_audio_devices_.size(), 1u);
646 ASSERT_GE(physical_video_devices_.size(), 1u);
648 media::AudioDeviceNames::const_iterator audio_it =
649 physical_audio_devices_.begin();
650 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
651 std::string source_id = content::GetHMACForMediaDeviceID(
652 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
653 origin_,
654 audio_it->unique_id);
655 ASSERT_FALSE(source_id.empty());
656 StreamOptions options(true, true);
657 AddSourceIdConstraint(source_id, &options.optional_audio);
659 SetupFakeUI(true);
660 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
661 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
664 media::VideoCaptureDevice::Names::const_iterator video_it =
665 physical_video_devices_.begin();
666 for (; video_it != physical_video_devices_.end(); ++video_it) {
667 std::string source_id = content::GetHMACForMediaDeviceID(
668 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
669 origin_,
670 video_it->id());
671 ASSERT_FALSE(source_id.empty());
672 StreamOptions options(true, true);
673 AddSourceIdConstraint(source_id, &options.optional_video);
675 SetupFakeUI(true);
676 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
677 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
681 // Test that generating a stream with an invalid mandatory video source id fail.
682 TEST_F(MediaStreamDispatcherHostTest,
683 GenerateStreamsWithInvalidMandatoryVideoSourceId) {
684 StreamOptions options(true, true);
685 AddSourceIdConstraint("invalid source id", &options.mandatory_video);
687 GenerateStreamAndWaitForFailure(
688 kRenderId,
689 kPageRequestId,
690 options,
691 MEDIA_DEVICE_NO_HARDWARE);
694 // Test that generating a stream with an invalid mandatory audio source id fail.
695 TEST_F(MediaStreamDispatcherHostTest,
696 GenerateStreamsWithInvalidMandatoryAudioSourceId) {
697 StreamOptions options(true, true);
698 AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
700 GenerateStreamAndWaitForFailure(
701 kRenderId,
702 kPageRequestId,
703 options,
704 MEDIA_DEVICE_NO_HARDWARE);
707 // Test that generating a stream with an invalid optional video source id
708 // succeed.
709 TEST_F(MediaStreamDispatcherHostTest,
710 GenerateStreamsWithInvalidOptionalVideoSourceId) {
711 StreamOptions options(true, true);
712 AddSourceIdConstraint("invalid source id", &options.optional_video);
714 SetupFakeUI(true);
715 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
718 // Test that generating a stream with an invalid optional audio source id
719 // succeed.
720 TEST_F(MediaStreamDispatcherHostTest,
721 GenerateStreamsWithInvalidOptionalAudioSourceId) {
722 StreamOptions options(true, true);
723 AddSourceIdConstraint("invalid source id", &options.optional_audio);
725 SetupFakeUI(true);
726 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
729 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
730 physical_video_devices_.clear();
731 video_capture_device_factory_->set_number_of_devices(0);
732 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
733 StreamOptions options(true, true);
735 SetupFakeUI(false);
736 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
737 MEDIA_DEVICE_NO_HARDWARE);
740 // Test that if a OnStopStreamDevice message is received for a device that has
741 // been opened in a MediaStream and by pepper, the device is only stopped for
742 // the MediaStream.
743 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
744 StreamOptions options(false, true);
746 SetupFakeUI(true);
747 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
749 std::string stream_request_label = host_->label_;
750 StreamDeviceInfo video_device_info = host_->video_devices_.front();
751 ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
752 stream_request_label).size());
754 // Open the same device by Pepper.
755 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
756 video_device_info.device.id);
757 std::string open_device_request_label = host_->label_;
759 // Stop the device in the MediaStream.
760 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
762 EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
763 stream_request_label).size());
764 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
765 open_device_request_label).size());
768 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
769 StreamOptions options(true, true);
771 SetupFakeUI(true);
772 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
774 std::string request_label1 = host_->label_;
775 StreamDeviceInfo video_device_info = host_->video_devices_.front();
776 // Expect that 1 audio and 1 video device has been opened.
777 EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
778 request_label1).size());
780 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
781 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
782 request_label1).size());
784 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
785 std::string request_label2 = host_->label_;
787 StreamDeviceInfoArray request1_devices =
788 media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
789 StreamDeviceInfoArray request2_devices =
790 media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
792 ASSERT_EQ(1u, request1_devices.size());
793 ASSERT_EQ(2u, request2_devices.size());
795 // Test that the same audio device has been opened in both streams.
796 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
797 request2_devices[0]) ||
798 StreamDeviceInfo::IsEqual(request1_devices[0],
799 request2_devices[1]));
802 TEST_F(MediaStreamDispatcherHostTest,
803 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
804 StreamOptions options(false, true);
806 SetupFakeUI(true);
807 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
808 EXPECT_EQ(host_->video_devices_.size(), 1u);
810 // Generate a second stream.
811 EXPECT_CALL(*host_.get(),
812 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
814 base::RunLoop run_loop1;
815 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
816 run_loop1.QuitClosure());
818 // Stop the video stream device from stream 1 while waiting for the
819 // second stream to be generated.
820 host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
821 run_loop1.Run();
823 EXPECT_EQ(host_->video_devices_.size(), 1u);
826 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
827 StreamOptions options(false, true);
829 base::RunLoop run_loop;
831 // Create multiple GenerateStream requests.
832 size_t streams = 5;
833 for (size_t i = 1; i <= streams; ++i) {
834 host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
835 run_loop.QuitClosure());
838 // Calling OnChannelClosing() to cancel all the pending requests.
839 host_->OnChannelClosing();
840 run_loop.RunUntilIdle();
843 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
844 StreamOptions options(false, true);
846 // Create first group of streams.
847 size_t generated_streams = 3;
848 for (size_t i = 0; i < generated_streams; ++i) {
849 SetupFakeUI(true);
850 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
853 // Calling OnChannelClosing() to cancel all the pending/generated streams.
854 host_->OnChannelClosing();
855 base::RunLoop().RunUntilIdle();
858 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
859 StreamOptions options(false, true);
861 base::Closure close_callback;
862 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
863 EXPECT_CALL(*stream_ui, OnStarted(_, _))
864 .WillOnce(SaveArg<0>(&close_callback));
865 media_stream_manager_->UseFakeUI(stream_ui.Pass());
867 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
869 EXPECT_EQ(host_->audio_devices_.size(), 0u);
870 EXPECT_EQ(host_->video_devices_.size(), 1u);
872 ASSERT_FALSE(close_callback.is_null());
873 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
874 close_callback.Run();
875 base::RunLoop().RunUntilIdle();
878 // Test that the dispatcher is notified if a video device that is in use is
879 // being unplugged.
880 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
881 StreamOptions options(true, true);
882 SetupFakeUI(true);
883 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
884 EXPECT_EQ(host_->audio_devices_.size(), 1u);
885 EXPECT_EQ(host_->video_devices_.size(), 1u);
887 video_capture_device_factory_->set_number_of_devices(0);
889 base::RunLoop run_loop;
890 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
891 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
892 media_stream_manager_->OnDevicesChanged(
893 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
895 run_loop.Run();
898 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
899 SetupFakeUI(false);
900 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
901 MEDIA_DEVICE_AUDIO_CAPTURE);
902 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
905 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
906 SetupFakeUI(false);
907 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
908 MEDIA_DEVICE_VIDEO_CAPTURE);
909 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
912 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevicesNoAccess) {
913 SetupFakeUI(false);
914 stream_ui_->SetMicAccess(false);
915 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
916 MEDIA_DEVICE_AUDIO_CAPTURE);
917 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
920 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevicesNoAccess) {
921 SetupFakeUI(false);
922 stream_ui_->SetCameraAccess(false);
923 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
924 MEDIA_DEVICE_VIDEO_CAPTURE);
925 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
928 }; // namespace content