Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / media / media_stream_dispatcher_host_unittest.cc
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.
4
5 #include <string>
6 #include <queue>
7
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"
35
36 #if defined(OS_CHROMEOS)
37 #include "chromeos/audio/cras_audio_handler.h"
38 #endif
39
40 using ::testing::_;
41 using ::testing::DeleteArg;
42 using ::testing::DoAll;
43 using ::testing::InSequence;
44 using ::testing::Return;
45 using ::testing::SaveArg;
46
47 const int kProcessId = 5;
48 const int kRenderId = 6;
49 const int kPageRequestId = 7;
50
51 namespace content {
52
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) {}
63
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));
73
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);
83   }
84
85   void OnStopStreamDevice(int render_frame_id,
86                           const std::string& device_id) {
87     MediaStreamDispatcherHost::OnStopStreamDevice(render_frame_id, device_id);
88   }
89
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);
99   }
100
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);
109   }
110
111   std::string label_;
112   StreamDeviceInfoArray audio_devices_;
113   StreamDeviceInfoArray video_devices_;
114   StreamDeviceInfo opened_device_;
115   StreamDeviceInfoArray enumerated_devices_;
116
117  private:
118   virtual ~MockMediaStreamDispatcherHost() {}
119
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;
126
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);
141
142     delete message;
143     current_ipc_ = NULL;
144     return true;
145   }
146
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));
159
160     label_ = label;
161     audio_devices_ = audio_device_list;
162     video_devices_ = video_device_list;
163   }
164
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));
173     }
174
175     label_= "";
176   }
177
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]));
184
185     OnDeviceStopped(current_ipc_->routing_id());
186   }
187
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;
196   }
197
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;
204   }
205
206   scoped_refptr<base::MessageLoopProxy> message_loop_;
207   IPC::Message* current_ipc_;
208   std::queue<base::Closure> quit_closures_;
209 };
210
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));
217 };
218
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
242
243     MockResourceContext* mock_resource_context =
244         static_cast<MockResourceContext*>(
245             browser_context_.GetResourceContext());
246
247     host_ = new MockMediaStreamDispatcherHost(
248         mock_resource_context->GetMediaDeviceIDSalt(),
249         base::MessageLoopProxy::current(),
250         media_stream_manager_.get());
251
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());
256
257 #if defined(OS_CHROMEOS)
258     chromeos::CrasAudioHandler::InitializeForTesting();
259 #endif
260   }
261
262   ~MediaStreamDispatcherHostTest() override {
263 #if defined(OS_CHROMEOS)
264     chromeos::CrasAudioHandler::Shutdown();
265 #endif
266   }
267
268   void SetUp() override {
269     video_capture_device_factory_->GetDeviceNames(&physical_video_devices_);
270     ASSERT_GT(physical_video_devices_.size(), 0u);
271
272     media_stream_manager_->audio_input_device_manager()->GetFakeDeviceNames(
273         &physical_audio_devices_);
274     ASSERT_GT(physical_audio_devices_.size(), 0u);
275   }
276
277   void TearDown() override { host_->OnChannelClosing(); }
278
279  protected:
280   virtual void SetupFakeUI(bool expect_started) {
281     stream_ui_ = new MockMediaStreamUIProxy();
282     if (expect_started) {
283       EXPECT_CALL(*stream_ui_, OnStarted(_, _));
284     }
285     media_stream_manager_->UseFakeUI(
286       scoped_ptr<FakeMediaStreamUIProxy>(stream_ui_));
287   }
288
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_));
310   }
311
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();
325   }
326
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_));
337   }
338
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_));
349   }
350
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;
358       }
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;
364       }
365     }
366     return false;
367   }
368
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;
383         }
384       }
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;
395         }
396       }
397       if (!found_match)
398         return false;
399     }
400     return true;
401   }
402
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;
408     }
409     return true;
410   }
411
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;
417     }
418     return true;
419   }
420
421   void AddSourceIdConstraint(const std::string& source_id,
422                              StreamOptions::Constraints* constraints) {
423     constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
424                                                      source_id));
425   }
426
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_;
439 };
440
441 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
442   StreamOptions options(false, true);
443
444   SetupFakeUI(true);
445   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
446
447   EXPECT_EQ(host_->audio_devices_.size(), 0u);
448   EXPECT_EQ(host_->video_devices_.size(), 1u);
449 }
450
451 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
452   StreamOptions options(true, false);
453
454   SetupFakeUI(true);
455   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
456
457   EXPECT_EQ(host_->audio_devices_.size(), 1u);
458   EXPECT_EQ(host_->video_devices_.size(), 0u);
459 }
460
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);
466
467   GenerateStreamAndWaitForFailure(
468       kRenderId,
469       kPageRequestId,
470       options,
471       MEDIA_DEVICE_FAILED_DUE_TO_SHUTDOWN);
472 }
473
474 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
475   StreamOptions options(true, true);
476
477   SetupFakeUI(true);
478   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
479
480   EXPECT_EQ(host_->audio_devices_.size(), 1u);
481   EXPECT_EQ(host_->video_devices_.size(), 1u);
482 }
483
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);
489
490   // Generate first stream.
491   SetupFakeUI(true);
492   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
493
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;
500
501   // Generate second stream.
502   SetupFakeUI(true);
503   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
504
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);
514 }
515
516 TEST_F(MediaStreamDispatcherHostTest,
517        GenerateStreamAndOpenDeviceFromSameRenderId) {
518   StreamOptions options(false, true);
519
520   // Generate first stream.
521   SetupFakeUI(true);
522   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
523
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;
529
530   // Generate second stream.
531   OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
532
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_;
536
537   EXPECT_EQ(device_id1, device_id2);
538   EXPECT_NE(session_id1, session_id2);
539   EXPECT_NE(label1, label2);
540 }
541
542
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);
547
548   // Generate first stream.
549   SetupFakeUI(true);
550   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
551
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;
558
559   // Generate second stream from another render frame.
560   SetupFakeUI(true);
561   GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, options);
562
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);
572 }
573
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);
579
580   // Generate first stream.
581   SetupFakeUI(true);
582   {
583     InSequence s;
584     EXPECT_CALL(*host_.get(),
585                 OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
586
587     // Generate second stream.
588     EXPECT_CALL(*host_.get(),
589                 OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
590   }
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());
597
598   run_loop1.Run();
599   run_loop2.Run();
600 }
601
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);
607
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);
618
619     SetupFakeUI(true);
620     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
621     EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
622   }
623
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);
634
635     SetupFakeUI(true);
636     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
637     EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
638   }
639 }
640
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);
646
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);
657
658     SetupFakeUI(true);
659     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
660     EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
661   }
662
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);
673
674     SetupFakeUI(true);
675     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
676     EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
677   }
678 }
679
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);
685
686   GenerateStreamAndWaitForFailure(
687       kRenderId,
688       kPageRequestId,
689       options,
690       MEDIA_DEVICE_NO_HARDWARE);
691 }
692
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);
698
699   GenerateStreamAndWaitForFailure(
700       kRenderId,
701       kPageRequestId,
702       options,
703       MEDIA_DEVICE_NO_HARDWARE);
704 }
705
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);
712
713   SetupFakeUI(true);
714   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
715 }
716
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);
723
724   SetupFakeUI(true);
725   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
726 }
727
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);
733
734   SetupFakeUI(false);
735   GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options,
736                                   MEDIA_DEVICE_NO_HARDWARE);
737 }
738
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);
744
745   SetupFakeUI(true);
746   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
747
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());
752
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_;
757
758   // Stop the device in the MediaStream.
759   host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
760
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());
765 }
766
767 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
768   StreamOptions options(true, true);
769
770   SetupFakeUI(true);
771   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
772
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());
778
779   host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
780   EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
781       request_label1).size());
782
783   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
784   std::string request_label2 = host_->label_;
785
786   StreamDeviceInfoArray request1_devices =
787       media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
788   StreamDeviceInfoArray request2_devices =
789       media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
790
791   ASSERT_EQ(1u, request1_devices.size());
792   ASSERT_EQ(2u, request2_devices.size());
793
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]));
799 }
800
801 TEST_F(MediaStreamDispatcherHostTest,
802        GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
803   StreamOptions options(false, true);
804
805   SetupFakeUI(true);
806   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
807   EXPECT_EQ(host_->video_devices_.size(), 1u);
808
809   // Generate a second stream.
810   EXPECT_CALL(*host_.get(),
811               OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
812
813   base::RunLoop run_loop1;
814   host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
815                           run_loop1.QuitClosure());
816
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();
821
822   EXPECT_EQ(host_->video_devices_.size(), 1u);
823 }
824
825 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
826   StreamOptions options(false, true);
827
828   base::RunLoop run_loop;
829
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());
835   }
836
837   // Calling OnChannelClosing() to cancel all the pending requests.
838   host_->OnChannelClosing();
839   run_loop.RunUntilIdle();
840 }
841
842 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
843   StreamOptions options(false, true);
844
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);
850   }
851
852   // Calling OnChannelClosing() to cancel all the pending/generated streams.
853   host_->OnChannelClosing();
854   base::RunLoop().RunUntilIdle();
855 }
856
857 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
858   StreamOptions options(false, true);
859
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());
865
866   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
867
868   EXPECT_EQ(host_->audio_devices_.size(), 0u);
869   EXPECT_EQ(host_->video_devices_.size(), 1u);
870
871   ASSERT_FALSE(close_callback.is_null());
872   EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
873   close_callback.Run();
874   base::RunLoop().RunUntilIdle();
875 }
876
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);
885
886   video_capture_device_factory_->set_number_of_devices(0);
887
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);
893
894   run_loop.Run();
895 }
896
897 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
898   SetupFakeUI(false);
899   EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
900                                    MEDIA_DEVICE_AUDIO_CAPTURE);
901   EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
902 }
903
904 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
905   SetupFakeUI(false);
906   EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
907                                    MEDIA_DEVICE_VIDEO_CAPTURE);
908   EXPECT_TRUE(DoesContainLabels(host_->enumerated_devices_));
909 }
910
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_));
917 }
918
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_));
925 }
926
927 };  // namespace content