Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_dispatcher_host_unittest.cc
blob4e9df5b5803ef3408095771b9ad130ff38bd482c
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <string>
6 #include <queue>
8 #include "base/bind.h"
9 #include "base/callback_helpers.h"
10 #include "base/command_line.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h"
13 #include "content/browser/browser_thread_impl.h"
14 #include "content/browser/renderer_host/media/audio_input_device_manager.h"
15 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
16 #include "content/browser/renderer_host/media/media_stream_manager.h"
17 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
18 #include "content/browser/renderer_host/media/video_capture_manager.h"
19 #include "content/common/media/media_stream_messages.h"
20 #include "content/common/media/media_stream_options.h"
21 #include "content/public/browser/media_device_id.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/mock_resource_context.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "content/public/test/test_browser_thread_bundle.h"
26 #include "content/test/test_content_browser_client.h"
27 #include "content/test/test_content_client.h"
28 #include "ipc/ipc_message_macros.h"
29 #include "media/audio/mock_audio_manager.h"
30 #include "media/base/media_switches.h"
31 #include "media/video/capture/fake_video_capture_device_factory.h"
32 #include "net/url_request/url_request_context.h"
33 #include "testing/gmock/include/gmock/gmock.h"
34 #include "testing/gtest/include/gtest/gtest.h"
36 using ::testing::_;
37 using ::testing::DeleteArg;
38 using ::testing::DoAll;
39 using ::testing::InSequence;
40 using ::testing::Return;
41 using ::testing::SaveArg;
43 const int kProcessId = 5;
44 const int kRenderId = 6;
45 const int kPageRequestId = 7;
47 namespace content {
49 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
50 public TestContentBrowserClient {
51 public:
52 MockMediaStreamDispatcherHost(
53 const ResourceContext::SaltCallback salt_callback,
54 const scoped_refptr<base::MessageLoopProxy>& message_loop,
55 MediaStreamManager* manager,
56 ResourceContext* resource_context)
57 : MediaStreamDispatcherHost(kProcessId, salt_callback, manager,
58 resource_context),
59 message_loop_(message_loop),
60 current_ipc_(NULL) {}
62 // A list of mock methods.
63 MOCK_METHOD4(OnStreamGenerated,
64 void(int routing_id, int request_id, int audio_array_size,
65 int video_array_size));
66 MOCK_METHOD3(OnStreamGenerationFailed, void(int routing_id,
67 int request_id,
68 MediaStreamRequestResult result));
69 MOCK_METHOD1(OnDeviceStopped, void(int routing_id));
70 MOCK_METHOD2(OnDeviceOpened, void(int routing_id, int request_id));
72 // Accessor to private functions.
73 void OnGenerateStream(int render_frame_id,
74 int page_request_id,
75 const StreamOptions& components,
76 const GURL& security_origin,
77 const base::Closure& quit_closure) {
78 quit_closures_.push(quit_closure);
79 MediaStreamDispatcherHost::OnGenerateStream(
80 render_frame_id, page_request_id, components, security_origin, false);
83 void OnStopStreamDevice(int render_frame_id,
84 const std::string& device_id) {
85 MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id, device_id);
88 void OnOpenDevice(int render_frame_id,
89 int page_request_id,
90 const std::string& device_id,
91 MediaStreamType type,
92 const GURL& security_origin,
93 const base::Closure& quit_closure) {
94 quit_closures_.push(quit_closure);
95 MediaStreamDispatcherHost::OnOpenDevice(
96 render_frame_id, page_request_id, device_id, type, security_origin);
99 void OnEnumerateDevices(int render_frame_id,
100 int page_request_id,
101 MediaStreamType type,
102 const GURL& security_origin,
103 const base::Closure& quit_closure) {
104 quit_closures_.push(quit_closure);
105 MediaStreamDispatcherHost::OnEnumerateDevices(
106 render_frame_id, page_request_id, type, security_origin);
109 std::string label_;
110 StreamDeviceInfoArray audio_devices_;
111 StreamDeviceInfoArray video_devices_;
112 StreamDeviceInfo opened_device_;
113 StreamDeviceInfoArray enumerated_devices_;
115 private:
116 virtual ~MockMediaStreamDispatcherHost() {}
118 // This method is used to dispatch IPC messages to the renderer. We intercept
119 // these messages here and dispatch to our mock methods to verify the
120 // conversation between this object and the renderer.
121 virtual bool Send(IPC::Message* message) OVERRIDE {
122 CHECK(message);
123 current_ipc_ = message;
125 // In this method we dispatch the messages to the according handlers as if
126 // we are the renderer.
127 bool handled = true;
128 IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message)
129 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated,
130 OnStreamGeneratedInternal)
131 IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed,
132 OnStreamGenerationFailedInternal)
133 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped, OnDeviceStoppedInternal)
134 IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened, OnDeviceOpenedInternal)
135 IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated, OnDevicesEnumerated)
136 IPC_MESSAGE_UNHANDLED(handled = false)
137 IPC_END_MESSAGE_MAP()
138 EXPECT_TRUE(handled);
140 delete message;
141 current_ipc_ = NULL;
142 return true;
145 // These handler methods do minimal things and delegate to the mock methods.
146 void OnStreamGeneratedInternal(
147 int request_id,
148 std::string label,
149 StreamDeviceInfoArray audio_device_list,
150 StreamDeviceInfoArray video_device_list) {
151 OnStreamGenerated(current_ipc_->routing_id(), request_id,
152 audio_device_list.size(), video_device_list.size());
153 // Notify that the event have occurred.
154 base::Closure quit_closure = quit_closures_.front();
155 quit_closures_.pop();
156 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
158 label_ = label;
159 audio_devices_ = audio_device_list;
160 video_devices_ = video_device_list;
163 void OnStreamGenerationFailedInternal(
164 int request_id,
165 content::MediaStreamRequestResult result) {
166 OnStreamGenerationFailed(current_ipc_->routing_id(), request_id, result);
167 if (!quit_closures_.empty()) {
168 base::Closure quit_closure = quit_closures_.front();
169 quit_closures_.pop();
170 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
173 label_= "";
176 void OnDeviceStoppedInternal(const std::string& label,
177 const content::StreamDeviceInfo& device) {
178 if (IsVideoMediaType(device.device.type))
179 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, video_devices_[0]));
180 if (IsAudioInputMediaType(device.device.type))
181 EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, audio_devices_[0]));
183 OnDeviceStopped(current_ipc_->routing_id());
186 void OnDeviceOpenedInternal(int request_id,
187 const std::string& label,
188 const StreamDeviceInfo& device) {
189 base::Closure quit_closure = quit_closures_.front();
190 quit_closures_.pop();
191 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
192 label_ = label;
193 opened_device_ = device;
196 void OnDevicesEnumerated(int request_id,
197 const StreamDeviceInfoArray& devices) {
198 base::Closure quit_closure = quit_closures_.front();
199 quit_closures_.pop();
200 message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
201 enumerated_devices_ = devices;
204 scoped_refptr<base::MessageLoopProxy> message_loop_;
205 IPC::Message* current_ipc_;
206 std::queue<base::Closure> quit_closures_;
209 class MockMediaStreamUIProxy : public FakeMediaStreamUIProxy {
210 public:
211 MOCK_METHOD2(
212 OnStarted,
213 void(const base::Closure& stop,
214 const MediaStreamUIProxy::WindowIdCallback& window_id_callback));
217 class MediaStreamDispatcherHostTest : public testing::Test {
218 public:
219 MediaStreamDispatcherHostTest()
220 : old_browser_client_(NULL),
221 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
222 origin_("https://test.com") {
223 audio_manager_.reset(
224 new media::MockAudioManager(base::MessageLoopProxy::current()));
225 // Make sure we use fake devices to avoid long delays.
226 base::CommandLine::ForCurrentProcess()->AppendSwitch(
227 switches::kUseFakeDeviceForMediaStream);
228 // Create our own MediaStreamManager.
229 media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
230 video_capture_device_factory_ =
231 static_cast<media::FakeVideoCaptureDeviceFactory*>(
232 media_stream_manager_->video_capture_manager()
233 ->video_capture_device_factory());
234 DCHECK(video_capture_device_factory_);
236 MockResourceContext* mock_resource_context =
237 static_cast<MockResourceContext*>(
238 browser_context_.GetResourceContext());
239 mock_resource_context->set_mic_access(true);
240 mock_resource_context->set_camera_access(true);
242 host_ = new MockMediaStreamDispatcherHost(
243 mock_resource_context->GetMediaDeviceIDSalt(),
244 base::MessageLoopProxy::current(),
245 media_stream_manager_.get(),
246 mock_resource_context);
248 // Use the fake content client and browser.
249 content_client_.reset(new TestContentClient());
250 SetContentClient(content_client_.get());
251 old_browser_client_ = SetBrowserClientForTesting(host_.get());
254 virtual ~MediaStreamDispatcherHostTest() {
257 virtual void SetUp() OVERRIDE {
258 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
259 ASSERT_GT(physical_video_devices_.size(), 0u);
261 media_stream_manager_->audio_input_device_manager()->GetFakeDeviceNames(
262 &physical_audio_devices_);
263 ASSERT_GT(physical_audio_devices_.size(), 0u);
266 virtual void TearDown() OVERRIDE {
267 host_->OnChannelClosing();
270 protected:
271 virtual void SetupFakeUI(bool expect_started) {
272 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
273 if (expect_started) {
274 EXPECT_CALL(*stream_ui, OnStarted(_, _));
276 media_stream_manager_->UseFakeUI(
277 stream_ui.PassAs<FakeMediaStreamUIProxy>());
280 void GenerateStreamAndWaitForResult(int render_frame_id,
281 int page_request_id,
282 const StreamOptions& options) {
283 base::RunLoop run_loop;
284 int expected_audio_array_size =
285 (options.audio_requested &&
286 physical_audio_devices_.size() > 0) ? 1 : 0;
287 int expected_video_array_size =
288 (options.video_requested &&
289 physical_video_devices_.size() > 0) ? 1 : 0;
290 EXPECT_CALL(*host_.get(), OnStreamGenerated(render_frame_id,
291 page_request_id,
292 expected_audio_array_size,
293 expected_video_array_size));
294 host_->OnGenerateStream(render_frame_id, page_request_id, options, origin_,
295 run_loop.QuitClosure());
296 run_loop.Run();
297 EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
298 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
299 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
300 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
303 void GenerateStreamAndWaitForFailure(
304 int render_frame_id,
305 int page_request_id,
306 const StreamOptions& options,
307 MediaStreamRequestResult expected_result) {
308 base::RunLoop run_loop;
309 EXPECT_CALL(*host_.get(),
310 OnStreamGenerationFailed(render_frame_id,
311 page_request_id,
312 expected_result));
313 host_->OnGenerateStream(render_frame_id, page_request_id, options,
314 origin_, run_loop.QuitClosure());
315 run_loop.Run();
318 void OpenVideoDeviceAndWaitForResult(int render_frame_id,
319 int page_request_id,
320 const std::string& device_id) {
321 base::RunLoop run_loop;
322 host_->OnOpenDevice(render_frame_id, page_request_id, device_id,
323 MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
324 run_loop.QuitClosure());
325 run_loop.Run();
326 EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
327 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
330 void EnumerateDevicesAndWaitForResult(int render_frame_id,
331 int page_request_id,
332 MediaStreamType type) {
333 base::RunLoop run_loop;
334 host_->OnEnumerateDevices(render_frame_id, page_request_id, type, origin_,
335 run_loop.QuitClosure());
336 run_loop.Run();
337 ASSERT_FALSE(host_->enumerated_devices_.empty());
338 EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
339 EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
342 bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
343 for (size_t i = 0; i < devices.size(); ++i) {
344 media::AudioDeviceNames::const_iterator audio_it =
345 physical_audio_devices_.begin();
346 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
347 if (audio_it->unique_id == devices[i].device.id)
348 return true;
350 media::VideoCaptureDevice::Names::const_iterator video_it =
351 physical_video_devices_.begin();
352 for (; video_it != physical_video_devices_.end(); ++video_it) {
353 if (video_it->id() == devices[i].device.id)
354 return true;
357 return false;
360 bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
361 const GURL& origin) {
362 for (size_t i = 0; i < devices.size(); ++i) {
363 bool found_match = false;
364 media::AudioDeviceNames::const_iterator audio_it =
365 physical_audio_devices_.begin();
366 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
367 if (content::DoesMediaDeviceIDMatchHMAC(
368 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
369 origin,
370 devices[i].device.id,
371 audio_it->unique_id)) {
372 EXPECT_FALSE(found_match);
373 found_match = true;
376 media::VideoCaptureDevice::Names::const_iterator video_it =
377 physical_video_devices_.begin();
378 for (; video_it != physical_video_devices_.end(); ++video_it) {
379 if (content::DoesMediaDeviceIDMatchHMAC(
380 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
381 origin,
382 devices[i].device.id,
383 video_it->id())) {
384 EXPECT_FALSE(found_match);
385 found_match = true;
388 if (!found_match)
389 return false;
391 return true;
394 // Returns true if all devices have labels, false otherwise.
395 bool DoesContainLabels(const StreamDeviceInfoArray& devices) {
396 for (size_t i = 0; i < devices.size(); ++i) {
397 if (devices[i].device.name.empty())
398 return false;
400 return true;
403 // Returns true if no devices have labels, false otherwise.
404 bool DoesNotContainLabels(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 void AddSourceIdConstraint(const std::string& source_id,
413 StreamOptions::Constraints* constraints) {
414 constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
415 source_id));
418 scoped_refptr<MockMediaStreamDispatcherHost> host_;
419 scoped_ptr<media::AudioManager> audio_manager_;
420 scoped_ptr<MediaStreamManager> media_stream_manager_;
421 ContentBrowserClient* old_browser_client_;
422 scoped_ptr<ContentClient> content_client_;
423 content::TestBrowserThreadBundle thread_bundle_;
424 content::TestBrowserContext browser_context_;
425 media::AudioDeviceNames physical_audio_devices_;
426 media::VideoCaptureDevice::Names physical_video_devices_;
427 GURL origin_;
428 media::FakeVideoCaptureDeviceFactory* video_capture_device_factory_;
431 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
432 StreamOptions options(false, true);
434 SetupFakeUI(true);
435 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
437 EXPECT_EQ(host_->audio_devices_.size(), 0u);
438 EXPECT_EQ(host_->video_devices_.size(), 1u);
441 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
442 StreamOptions options(true, false);
444 SetupFakeUI(true);
445 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
447 EXPECT_EQ(host_->audio_devices_.size(), 1u);
448 EXPECT_EQ(host_->video_devices_.size(), 0u);
451 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
452 StreamOptions options(false, false);
454 GenerateStreamAndWaitForFailure(
455 kRenderId,
456 kPageRequestId,
457 options,
458 MEDIA_DEVICE_INVALID_STATE);
461 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
462 StreamOptions options(true, true);
464 SetupFakeUI(true);
465 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
467 EXPECT_EQ(host_->audio_devices_.size(), 1u);
468 EXPECT_EQ(host_->video_devices_.size(), 1u);
471 // This test generates two streams with video only using the same render frame
472 // id. The same capture device with the same device and session id is expected
473 // to be used.
474 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
475 StreamOptions options(false, true);
477 // Generate first stream.
478 SetupFakeUI(true);
479 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
481 // Check the latest generated stream.
482 EXPECT_EQ(host_->audio_devices_.size(), 0u);
483 EXPECT_EQ(host_->video_devices_.size(), 1u);
484 const std::string label1 = host_->label_;
485 const std::string device_id1 = host_->video_devices_.front().device.id;
486 const int session_id1 = host_->video_devices_.front().session_id;
488 // Generate second stream.
489 SetupFakeUI(true);
490 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
492 // Check the latest generated stream.
493 EXPECT_EQ(host_->audio_devices_.size(), 0u);
494 EXPECT_EQ(host_->video_devices_.size(), 1u);
495 const std::string label2 = host_->label_;
496 const std::string device_id2 = host_->video_devices_.front().device.id;
497 int session_id2 = host_->video_devices_.front().session_id;
498 EXPECT_EQ(device_id1, device_id2);
499 EXPECT_EQ(session_id1, session_id2);
500 EXPECT_NE(label1, label2);
503 TEST_F(MediaStreamDispatcherHostTest,
504 GenerateStreamAndOpenDeviceFromSameRenderId) {
505 StreamOptions options(false, true);
507 // Generate first stream.
508 SetupFakeUI(true);
509 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
511 EXPECT_EQ(host_->audio_devices_.size(), 0u);
512 EXPECT_EQ(host_->video_devices_.size(), 1u);
513 const std::string label1 = host_->label_;
514 const std::string device_id1 = host_->video_devices_.front().device.id;
515 const int session_id1 = host_->video_devices_.front().session_id;
517 // Generate second stream.
518 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
520 const std::string device_id2 = host_->opened_device_.device.id;
521 const int session_id2 = host_->opened_device_.session_id;
522 const std::string label2 = host_->label_;
524 EXPECT_EQ(device_id1, device_id2);
525 EXPECT_NE(session_id1, session_id2);
526 EXPECT_NE(label1, label2);
530 // This test generates two streams with video only using two separate render
531 // frame ids. The same device id but different session ids are expected.
532 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
533 StreamOptions options(false, true);
535 // Generate first stream.
536 SetupFakeUI(true);
537 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
539 // Check the latest generated stream.
540 EXPECT_EQ(host_->audio_devices_.size(), 0u);
541 EXPECT_EQ(host_->video_devices_.size(), 1u);
542 const std::string label1 = host_->label_;
543 const std::string device_id1 = host_->video_devices_.front().device.id;
544 const int session_id1 = host_->video_devices_.front().session_id;
546 // Generate second stream from another render frame.
547 SetupFakeUI(true);
548 GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
550 // Check the latest generated stream.
551 EXPECT_EQ(host_->audio_devices_.size(), 0u);
552 EXPECT_EQ(host_->video_devices_.size(), 1u);
553 const std::string label2 = host_->label_;
554 const std::string device_id2 = host_->video_devices_.front().device.id;
555 const int session_id2 = host_->video_devices_.front().session_id;
556 EXPECT_EQ(device_id1, device_id2);
557 EXPECT_NE(session_id1, session_id2);
558 EXPECT_NE(label1, label2);
561 // This test request two streams with video only without waiting for the first
562 // stream to be generated before requesting the second.
563 // The same device id and session ids are expected.
564 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
565 StreamOptions options(false, true);
567 // Generate first stream.
568 SetupFakeUI(true);
570 InSequence s;
571 EXPECT_CALL(*host_.get(),
572 OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
574 // Generate second stream.
575 EXPECT_CALL(*host_.get(),
576 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
578 base::RunLoop run_loop1;
579 base::RunLoop run_loop2;
580 host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
581 run_loop1.QuitClosure());
582 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
583 run_loop2.QuitClosure());
585 run_loop1.Run();
586 run_loop2.Run();
589 // Test that we can generate streams where a mandatory sourceId is specified in
590 // the request.
591 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
592 ASSERT_GE(physical_audio_devices_.size(), 1u);
593 ASSERT_GE(physical_video_devices_.size(), 1u);
595 media::AudioDeviceNames::const_iterator audio_it =
596 physical_audio_devices_.begin();
597 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
598 std::string source_id = content::GetHMACForMediaDeviceID(
599 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
600 origin_,
601 audio_it->unique_id);
602 ASSERT_FALSE(source_id.empty());
603 StreamOptions options(true, true);
604 AddSourceIdConstraint(source_id, &options.mandatory_audio);
606 SetupFakeUI(true);
607 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
608 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
611 media::VideoCaptureDevice::Names::const_iterator video_it =
612 physical_video_devices_.begin();
613 for (; video_it != physical_video_devices_.end(); ++video_it) {
614 std::string source_id = content::GetHMACForMediaDeviceID(
615 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
616 origin_,
617 video_it->id());
618 ASSERT_FALSE(source_id.empty());
619 StreamOptions options(true, true);
620 AddSourceIdConstraint(source_id, &options.mandatory_video);
622 SetupFakeUI(true);
623 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
624 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
628 // Test that we can generate streams where a optional sourceId is specified in
629 // the request.
630 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
631 ASSERT_GE(physical_audio_devices_.size(), 1u);
632 ASSERT_GE(physical_video_devices_.size(), 1u);
634 media::AudioDeviceNames::const_iterator audio_it =
635 physical_audio_devices_.begin();
636 for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
637 std::string source_id = content::GetHMACForMediaDeviceID(
638 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
639 origin_,
640 audio_it->unique_id);
641 ASSERT_FALSE(source_id.empty());
642 StreamOptions options(true, true);
643 AddSourceIdConstraint(source_id, &options.optional_audio);
645 SetupFakeUI(true);
646 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
647 EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
650 media::VideoCaptureDevice::Names::const_iterator video_it =
651 physical_video_devices_.begin();
652 for (; video_it != physical_video_devices_.end(); ++video_it) {
653 std::string source_id = content::GetHMACForMediaDeviceID(
654 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
655 origin_,
656 video_it->id());
657 ASSERT_FALSE(source_id.empty());
658 StreamOptions options(true, true);
659 AddSourceIdConstraint(source_id, &options.optional_video);
661 SetupFakeUI(true);
662 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
663 EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
667 // Test that generating a stream with an invalid mandatory video source id fail.
668 TEST_F(MediaStreamDispatcherHostTest,
669 GenerateStreamsWithInvalidMandatoryVideoSourceId) {
670 StreamOptions options(true, true);
671 AddSourceIdConstraint("invalid source id", &options.mandatory_video);
673 GenerateStreamAndWaitForFailure(
674 kRenderId,
675 kPageRequestId,
676 options,
677 MEDIA_DEVICE_NO_HARDWARE);
680 // Test that generating a stream with an invalid mandatory audio source id fail.
681 TEST_F(MediaStreamDispatcherHostTest,
682 GenerateStreamsWithInvalidMandatoryAudioSourceId) {
683 StreamOptions options(true, true);
684 AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
686 GenerateStreamAndWaitForFailure(
687 kRenderId,
688 kPageRequestId,
689 options,
690 MEDIA_DEVICE_NO_HARDWARE);
693 // Test that generating a stream with an invalid optional video source id
694 // succeed.
695 TEST_F(MediaStreamDispatcherHostTest,
696 GenerateStreamsWithInvalidOptionalVideoSourceId) {
697 StreamOptions options(true, true);
698 AddSourceIdConstraint("invalid source id", &options.optional_video);
700 SetupFakeUI(true);
701 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
704 // Test that generating a stream with an invalid optional audio source id
705 // succeed.
706 TEST_F(MediaStreamDispatcherHostTest,
707 GenerateStreamsWithInvalidOptionalAudioSourceId) {
708 StreamOptions options(true, true);
709 AddSourceIdConstraint("invalid source id", &options.optional_audio);
711 SetupFakeUI(true);
712 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
715 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
716 physical_video_devices_.clear();
717 video_capture_device_factory_->set_number_of_devices(0);
718 video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
719 StreamOptions options(true, true);
721 SetupFakeUI(false);
722 GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
723 MEDIA_DEVICE_NO_HARDWARE);
726 // Test that if a OnStopStreamDevice message is received for a device that has
727 // been opened in a MediaStream and by pepper, the device is only stopped for
728 // the MediaStream.
729 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
730 StreamOptions options(false, true);
732 SetupFakeUI(true);
733 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
735 std::string stream_request_label = host_->label_;
736 StreamDeviceInfo video_device_info = host_->video_devices_.front();
737 ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
738 stream_request_label).size());
740 // Open the same device by Pepper.
741 OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
742 video_device_info.device.id);
743 std::string open_device_request_label = host_->label_;
745 // Stop the device in the MediaStream.
746 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
748 EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
749 stream_request_label).size());
750 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
751 open_device_request_label).size());
754 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
755 StreamOptions options(true, true);
757 SetupFakeUI(true);
758 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
760 std::string request_label1 = host_->label_;
761 StreamDeviceInfo video_device_info = host_->video_devices_.front();
762 // Expect that 1 audio and 1 video device has been opened.
763 EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
764 request_label1).size());
766 host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
767 EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
768 request_label1).size());
770 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
771 std::string request_label2 = host_->label_;
773 StreamDeviceInfoArray request1_devices =
774 media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
775 StreamDeviceInfoArray request2_devices =
776 media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
778 ASSERT_EQ(1u, request1_devices.size());
779 ASSERT_EQ(2u, request2_devices.size());
781 // Test that the same audio device has been opened in both streams.
782 EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
783 request2_devices[0]) ||
784 StreamDeviceInfo::IsEqual(request1_devices[0],
785 request2_devices[1]));
788 TEST_F(MediaStreamDispatcherHostTest,
789 GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
790 StreamOptions options(false, true);
792 SetupFakeUI(true);
793 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
794 EXPECT_EQ(host_->video_devices_.size(), 1u);
796 // Generate a second stream.
797 EXPECT_CALL(*host_.get(),
798 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
800 base::RunLoop run_loop1;
801 host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
802 run_loop1.QuitClosure());
804 // Stop the video stream device from stream 1 while waiting for the
805 // second stream to be generated.
806 host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
807 run_loop1.Run();
809 EXPECT_EQ(host_->video_devices_.size(), 1u);
812 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
813 StreamOptions options(false, true);
815 base::RunLoop run_loop;
817 // Create multiple GenerateStream requests.
818 size_t streams = 5;
819 for (size_t i = 1; i <= streams; ++i) {
820 host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
821 run_loop.QuitClosure());
824 // Calling OnChannelClosing() to cancel all the pending requests.
825 host_->OnChannelClosing();
826 run_loop.RunUntilIdle();
829 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
830 StreamOptions options(false, true);
832 // Create first group of streams.
833 size_t generated_streams = 3;
834 for (size_t i = 0; i < generated_streams; ++i) {
835 SetupFakeUI(true);
836 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
839 // Calling OnChannelClosing() to cancel all the pending/generated streams.
840 host_->OnChannelClosing();
841 base::RunLoop().RunUntilIdle();
844 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
845 StreamOptions options(false, true);
847 base::Closure close_callback;
848 scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
849 EXPECT_CALL(*stream_ui, OnStarted(_, _))
850 .WillOnce(SaveArg<0>(&close_callback));
851 media_stream_manager_->UseFakeUI(stream_ui.PassAs<FakeMediaStreamUIProxy>());
853 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
855 EXPECT_EQ(host_->audio_devices_.size(), 0u);
856 EXPECT_EQ(host_->video_devices_.size(), 1u);
858 ASSERT_FALSE(close_callback.is_null());
859 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
860 close_callback.Run();
861 base::RunLoop().RunUntilIdle();
864 // Test that the dispatcher is notified if a video device that is in use is
865 // being unplugged.
866 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
867 StreamOptions options(true, true);
868 SetupFakeUI(true);
869 GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
870 EXPECT_EQ(host_->audio_devices_.size(), 1u);
871 EXPECT_EQ(host_->video_devices_.size(), 1u);
873 video_capture_device_factory_->set_number_of_devices(0);
875 base::RunLoop run_loop;
876 EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
877 .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
878 media_stream_manager_->OnDevicesChanged(
879 base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
881 run_loop.Run();
884 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
885 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
886 MEDIA_DEVICE_AUDIO_CAPTURE);
887 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
890 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
891 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
892 MEDIA_DEVICE_VIDEO_CAPTURE);
893 EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
896 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevicesNoAccess) {
897 MockResourceContext* mock_resource_context =
898 static_cast<MockResourceContext*>(browser_context_.GetResourceContext());
899 mock_resource_context->set_mic_access(false);
900 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
901 MEDIA_DEVICE_AUDIO_CAPTURE);
902 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
905 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevicesNoAccess) {
906 MockResourceContext* mock_resource_context =
907 static_cast<MockResourceContext*>(browser_context_.GetResourceContext());
908 mock_resource_context->set_camera_access(false);
909 EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
910 MEDIA_DEVICE_VIDEO_CAPTURE);
911 EXPECT_TRUE(DoesNotContainLabels(host_->enumerated_devices_));
914 }; // namespace content