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