Upstream version 5.34.104.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/message_loop/message_loop.h"
11 #include "base/run_loop.h"
12 #include "content/browser/browser_thread_impl.h"
13 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
14 #include "content/browser/renderer_host/media/media_stream_manager.h"
15 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
16 #include "content/common/media/media_stream_messages.h"
17 #include "content/common/media/media_stream_options.h"
18 #include "content/public/browser/media_device_id.h"
19 #include "content/public/test/mock_resource_context.h"
20 #include "content/public/test/test_browser_context.h"
21 #include "content/public/test/test_browser_thread_bundle.h"
22 #include "content/test/test_content_browser_client.h"
23 #include "content/test/test_content_client.h"
24 #include "ipc/ipc_message_macros.h"
25 #include "media/audio/mock_audio_manager.h"
26 #include "media/video/capture/fake_video_capture_device.h"
27 #include "net/url_request/url_request_context.h"
28 #include "testing/gmock/include/gmock/gmock.h"
29 #include "testing/gtest/include/gtest/gtest.h"
30
31 using ::testing::_;
32 using ::testing::DeleteArg;
33 using ::testing::DoAll;
34 using ::testing::Return;
35 using ::testing::SaveArg;
36
37 const int kProcessId = 5;
38 const int kRenderId = 6;
39 const int kPageRequestId = 7;
40
41 namespace content {
42
43 class MockMediaStreamDispatcherHost : public MediaStreamDispatcherHost,
44                                       public TestContentBrowserClient {
45  public:
46   MockMediaStreamDispatcherHost(
47       const ResourceContext::SaltCallback salt_callback,
48       const scoped_refptr<base::MessageLoopProxy>& message_loop,
49       MediaStreamManager* manager)
50       : MediaStreamDispatcherHost(kProcessId, salt_callback, manager),
51         message_loop_(message_loop) {}
52
53   // A list of mock methods.
54   MOCK_METHOD4(OnStreamGenerated,
55                void(int routing_id, int request_id, int audio_array_size,
56                     int video_array_size));
57   MOCK_METHOD2(OnStreamGenerationFailed, void(int routing_id, int request_id));
58   MOCK_METHOD1(OnDeviceStopped, void(int routing_id));
59   MOCK_METHOD2(OnDeviceOpened, void(int routing_id, int request_id));
60
61   // Accessor to private functions.
62   void OnGenerateStream(int render_view_id,
63                         int page_request_id,
64                         const StreamOptions& components,
65                         const GURL& security_origin,
66                         const base::Closure& quit_closure) {
67     quit_closures_.push(quit_closure);
68     MediaStreamDispatcherHost::OnGenerateStream(
69         render_view_id, page_request_id, components, security_origin);
70   }
71
72   void OnStopStreamDevice(int render_view_id,
73                           const std::string& device_id) {
74     MediaStreamDispatcherHost::OnStopStreamDevice(render_view_id, device_id);
75   }
76
77   void OnOpenDevice(int render_view_id,
78                     int page_request_id,
79                     const std::string& device_id,
80                     MediaStreamType type,
81                     const GURL& security_origin,
82                     const base::Closure& quit_closure) {
83     quit_closures_.push(quit_closure);
84     MediaStreamDispatcherHost::OnOpenDevice(
85         render_view_id, page_request_id, device_id, type, security_origin);
86   }
87
88   void OnEnumerateDevices(int render_view_id,
89                           int page_request_id,
90                           MediaStreamType type,
91                           const GURL& security_origin,
92                           const base::Closure& quit_closure) {
93     quit_closures_.push(quit_closure);
94     MediaStreamDispatcherHost::OnEnumerateDevices(
95         render_view_id, page_request_id, type, security_origin);
96   }
97
98   std::string label_;
99   StreamDeviceInfoArray audio_devices_;
100   StreamDeviceInfoArray video_devices_;
101   StreamDeviceInfo opened_device_;
102   StreamDeviceInfoArray enumerated_devices_;
103
104  private:
105   virtual ~MockMediaStreamDispatcherHost() {}
106
107   // This method is used to dispatch IPC messages to the renderer. We intercept
108   // these messages here and dispatch to our mock methods to verify the
109   // conversation between this object and the renderer.
110   virtual bool Send(IPC::Message* message) OVERRIDE {
111     CHECK(message);
112
113     // In this method we dispatch the messages to the according handlers as if
114     // we are the renderer.
115     bool handled = true;
116     IPC_BEGIN_MESSAGE_MAP(MockMediaStreamDispatcherHost, *message)
117       IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerated, OnStreamGenerated)
118       IPC_MESSAGE_HANDLER(MediaStreamMsg_StreamGenerationFailed,
119                           OnStreamGenerationFailed)
120       IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceStopped, OnDeviceStopped)
121       IPC_MESSAGE_HANDLER(MediaStreamMsg_DeviceOpened, OnDeviceOpened)
122       IPC_MESSAGE_HANDLER(MediaStreamMsg_DevicesEnumerated,
123                           OnDevicesEnumerated)
124       IPC_MESSAGE_UNHANDLED(handled = false)
125     IPC_END_MESSAGE_MAP()
126     EXPECT_TRUE(handled);
127
128     delete message;
129     return true;
130   }
131
132   // These handler methods do minimal things and delegate to the mock methods.
133   void OnStreamGenerated(
134       const IPC::Message& msg,
135       int request_id,
136       std::string label,
137       StreamDeviceInfoArray audio_device_list,
138       StreamDeviceInfoArray video_device_list) {
139     OnStreamGenerated(msg.routing_id(), request_id, audio_device_list.size(),
140         video_device_list.size());
141     // Notify that the event have occurred.
142     base::Closure quit_closure = quit_closures_.front();
143     quit_closures_.pop();
144     message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
145
146     label_ = label;
147     audio_devices_ = audio_device_list;
148     video_devices_ = video_device_list;
149   }
150
151   void OnStreamGenerationFailed(const IPC::Message& msg, int request_id) {
152     OnStreamGenerationFailed(msg.routing_id(), request_id);
153     if (!quit_closures_.empty()) {
154       base::Closure quit_closure = quit_closures_.front();
155       quit_closures_.pop();
156       message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
157     }
158
159     label_= "";
160   }
161
162   void OnDeviceStopped(const IPC::Message& msg,
163                        const std::string& label,
164                        const content::StreamDeviceInfo& device) {
165     if (IsVideoMediaType(device.device.type))
166       EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, video_devices_[0]));
167     if (IsAudioMediaType(device.device.type))
168       EXPECT_TRUE(StreamDeviceInfo::IsEqual(device, audio_devices_[0]));
169
170     OnDeviceStopped(msg.routing_id());
171   }
172
173   void OnDeviceOpened(const IPC::Message& msg,
174                       int request_id,
175                       const std::string& label,
176                       const StreamDeviceInfo& device) {
177     base::Closure quit_closure = quit_closures_.front();
178     quit_closures_.pop();
179     message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
180     label_ = label;
181     opened_device_ = device;
182   }
183
184   void OnDevicesEnumerated(const IPC::Message& msg,
185                            int request_id,
186                            const StreamDeviceInfoArray& devices) {
187     base::Closure quit_closure = quit_closures_.front();
188     quit_closures_.pop();
189     message_loop_->PostTask(FROM_HERE, base::ResetAndReturn(&quit_closure));
190     enumerated_devices_ = devices;
191   }
192
193   scoped_refptr<base::MessageLoopProxy> message_loop_;
194
195   std::queue<base::Closure> quit_closures_;
196 };
197
198 class MockMediaStreamUIProxy : public FakeMediaStreamUIProxy {
199  public:
200   MOCK_METHOD1(OnStarted, void(const base::Closure& stop));
201 };
202
203 class MediaStreamDispatcherHostTest : public testing::Test {
204  public:
205   MediaStreamDispatcherHostTest()
206       : old_browser_client_(NULL),
207         thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
208         origin_("https://test.com") {
209     audio_manager_.reset(
210         new media::MockAudioManager(base::MessageLoopProxy::current()));
211     // Create our own MediaStreamManager.
212     media_stream_manager_.reset(new MediaStreamManager(audio_manager_.get()));
213     // Make sure we use fake devices to avoid long delays.
214     media_stream_manager_->UseFakeDevice();
215
216     host_ = new MockMediaStreamDispatcherHost(
217         browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
218         base::MessageLoopProxy::current(),
219         media_stream_manager_.get());
220
221     // Use the fake content client and browser.
222     content_client_.reset(new TestContentClient());
223     SetContentClient(content_client_.get());
224     old_browser_client_ = SetBrowserClientForTesting(host_.get());
225   }
226
227   virtual ~MediaStreamDispatcherHostTest() {
228   }
229
230   virtual void SetUp() OVERRIDE {
231     media::FakeVideoCaptureDevice::GetDeviceNames(&physical_video_devices_);
232     ASSERT_GT(physical_video_devices_.size(), 0u);
233
234     audio_manager_->GetAudioInputDeviceNames(&physical_audio_devices_);
235     ASSERT_GT(physical_audio_devices_.size(), 0u);
236   }
237
238   virtual void TearDown() OVERRIDE {
239     host_->OnChannelClosing();
240   }
241
242  protected:
243   virtual void SetupFakeUI(bool expect_started) {
244     scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
245     if (expect_started) {
246       EXPECT_CALL(*stream_ui, OnStarted(_));
247     }
248     media_stream_manager_->UseFakeUI(
249         stream_ui.PassAs<FakeMediaStreamUIProxy>());
250   }
251
252   void GenerateStreamAndWaitForResult(int render_view_id,
253                                       int page_request_id,
254                                       const StreamOptions& options) {
255     base::RunLoop run_loop;
256     int expected_audio_array_size =
257         (options.audio_requested &&
258          physical_audio_devices_.size() > 0) ? 1 : 0;
259     int expected_video_array_size =
260         (options.video_requested &&
261          physical_video_devices_.size() > 0) ? 1 : 0;
262     EXPECT_CALL(*host_.get(), OnStreamGenerated(render_view_id, page_request_id,
263                                                 expected_audio_array_size,
264                                                 expected_video_array_size));
265     host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
266                             run_loop.QuitClosure());
267     run_loop.Run();
268     EXPECT_FALSE(DoesContainRawIds(host_->audio_devices_));
269     EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
270     EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->audio_devices_, origin_));
271     EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
272   }
273
274   void GenerateStreamAndWaitForFailure(int render_view_id,
275                                        int page_request_id,
276                                        const StreamOptions& options) {
277       base::RunLoop run_loop;
278       EXPECT_CALL(*host_.get(),
279                   OnStreamGenerationFailed(render_view_id, page_request_id));
280       host_->OnGenerateStream(render_view_id, page_request_id, options, origin_,
281                               run_loop.QuitClosure());
282       run_loop.Run();
283   }
284
285   void OpenVideoDeviceAndWaitForResult(int render_view_id,
286                                        int page_request_id,
287                                        const std::string& device_id) {
288     base::RunLoop run_loop;
289     host_->OnOpenDevice(render_view_id, page_request_id, device_id,
290                         MEDIA_DEVICE_VIDEO_CAPTURE, origin_,
291                         run_loop.QuitClosure());
292     run_loop.Run();
293     EXPECT_FALSE(DoesContainRawIds(host_->video_devices_));
294     EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->video_devices_, origin_));
295   }
296
297   void EnumerateDevicesAndWaitForResult(int render_view_id,
298                                         int page_request_id,
299                                         MediaStreamType type) {
300     base::RunLoop run_loop;
301     host_->OnEnumerateDevices(render_view_id, page_request_id, type, origin_,
302                               run_loop.QuitClosure());
303     run_loop.Run();
304     ASSERT_FALSE(host_->enumerated_devices_.empty());
305     EXPECT_FALSE(DoesContainRawIds(host_->enumerated_devices_));
306     EXPECT_TRUE(DoesEveryDeviceMapToRawId(host_->enumerated_devices_, origin_));
307   }
308
309   bool DoesContainRawIds(const StreamDeviceInfoArray& devices) {
310     for (size_t i = 0; i < devices.size(); ++i) {
311       media::AudioDeviceNames::const_iterator audio_it =
312           physical_audio_devices_.begin();
313       for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
314         if (audio_it->unique_id == devices[i].device.id)
315           return true;
316       }
317       media::VideoCaptureDevice::Names::const_iterator video_it =
318           physical_video_devices_.begin();
319       for (; video_it != physical_video_devices_.end(); ++video_it) {
320         if (video_it->id() == devices[i].device.id)
321           return true;
322       }
323     }
324     return false;
325   }
326
327   bool DoesEveryDeviceMapToRawId(const StreamDeviceInfoArray& devices,
328                                  const GURL& origin) {
329     for (size_t i = 0; i < devices.size(); ++i) {
330       bool found_match = false;
331       media::AudioDeviceNames::const_iterator audio_it =
332           physical_audio_devices_.begin();
333       for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
334         if (content::DoesMediaDeviceIDMatchHMAC(
335                 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
336                 origin,
337                 devices[i].device.id,
338                 audio_it->unique_id)) {
339           EXPECT_FALSE(found_match);
340           found_match = true;
341         }
342       }
343       media::VideoCaptureDevice::Names::const_iterator video_it =
344           physical_video_devices_.begin();
345       for (; video_it != physical_video_devices_.end(); ++video_it) {
346         if (content::DoesMediaDeviceIDMatchHMAC(
347                 browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
348                 origin,
349                 devices[i].device.id,
350                 video_it->id())) {
351           EXPECT_FALSE(found_match);
352           found_match = true;
353         }
354       }
355       if (!found_match)
356         return false;
357     }
358     return true;
359   }
360
361   void AddSourceIdConstraint(const std::string& source_id,
362                              StreamOptions::Constraints* constraints) {
363     constraints->push_back(StreamOptions::Constraint(kMediaStreamSourceInfoId,
364                                                      source_id));
365   }
366
367   scoped_refptr<MockMediaStreamDispatcherHost> host_;
368   scoped_ptr<media::AudioManager> audio_manager_;
369   scoped_ptr<MediaStreamManager> media_stream_manager_;
370   ContentBrowserClient* old_browser_client_;
371   scoped_ptr<ContentClient> content_client_;
372   content::TestBrowserThreadBundle thread_bundle_;
373   content::TestBrowserContext browser_context_;
374   media::AudioDeviceNames physical_audio_devices_;
375   media::VideoCaptureDevice::Names physical_video_devices_;
376   GURL origin_;
377 };
378
379 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithVideoOnly) {
380   StreamOptions options(false, true);
381
382   SetupFakeUI(true);
383   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
384
385   EXPECT_EQ(host_->audio_devices_.size(), 0u);
386   EXPECT_EQ(host_->video_devices_.size(), 1u);
387 }
388
389 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioOnly) {
390   StreamOptions options(true, false);
391
392   SetupFakeUI(true);
393   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
394
395   EXPECT_EQ(host_->audio_devices_.size(), 1u);
396   EXPECT_EQ(host_->video_devices_.size(), 0u);
397 }
398
399 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithNothing) {
400   StreamOptions options(false, false);
401
402   GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options);
403 }
404
405 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamWithAudioAndVideo) {
406   StreamOptions options(true, true);
407
408   SetupFakeUI(true);
409   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
410
411   EXPECT_EQ(host_->audio_devices_.size(), 1u);
412   EXPECT_EQ(host_->video_devices_.size(), 1u);
413 }
414
415 // This test generates two streams with video only using the same render view
416 // id. The same capture device  with the same device and session id is expected
417 // to be used.
418 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsFromSameRenderId) {
419   StreamOptions options(false, true);
420
421   // Generate first stream.
422   SetupFakeUI(true);
423   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
424
425   // Check the latest generated stream.
426   EXPECT_EQ(host_->audio_devices_.size(), 0u);
427   EXPECT_EQ(host_->video_devices_.size(), 1u);
428   const std::string label1 = host_->label_;
429   const std::string device_id1 = host_->video_devices_.front().device.id;
430   const int session_id1 = host_->video_devices_.front().session_id;
431
432   // Generate second stream.
433   SetupFakeUI(true);
434   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + 1, options);
435
436   // Check the latest generated stream.
437   EXPECT_EQ(host_->audio_devices_.size(), 0u);
438   EXPECT_EQ(host_->video_devices_.size(), 1u);
439   const std::string label2 = host_->label_;
440   const std::string device_id2 = host_->video_devices_.front().device.id;
441   int session_id2 = host_->video_devices_.front().session_id;
442   EXPECT_EQ(device_id1, device_id2);
443   EXPECT_EQ(session_id1, session_id2);
444   EXPECT_NE(label1, label2);
445 }
446
447 TEST_F(MediaStreamDispatcherHostTest,
448        GenerateStreamAndOpenDeviceFromSameRenderId) {
449   StreamOptions options(false, true);
450
451   // Generate first stream.
452   SetupFakeUI(true);
453   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
454
455   EXPECT_EQ(host_->audio_devices_.size(), 0u);
456   EXPECT_EQ(host_->video_devices_.size(), 1u);
457   const std::string label1 = host_->label_;
458   const std::string device_id1 = host_->video_devices_.front().device.id;
459   const int session_id1 = host_->video_devices_.front().session_id;
460
461   // Generate second stream.
462   OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId, device_id1);
463
464   const std::string device_id2 = host_->opened_device_.device.id;
465   const int session_id2 = host_->opened_device_.session_id;
466   const std::string label2 = host_->label_;
467
468   EXPECT_EQ(device_id1, device_id2);
469   EXPECT_NE(session_id1, session_id2);
470   EXPECT_NE(label1, label2);
471 }
472
473
474 // This test generates two streams with video only using two separate render
475 // view ids. The same device id but different session ids are expected.
476 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsDifferentRenderId) {
477   StreamOptions options(false, true);
478
479   // Generate first stream.
480   SetupFakeUI(true);
481   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
482
483   // Check the latest generated stream.
484   EXPECT_EQ(host_->audio_devices_.size(), 0u);
485   EXPECT_EQ(host_->video_devices_.size(), 1u);
486   const std::string label1 = host_->label_;
487   const std::string device_id1 = host_->video_devices_.front().device.id;
488   const int session_id1 = host_->video_devices_.front().session_id;
489
490   // Generate second stream from another render view.
491   SetupFakeUI(true);
492   GenerateStreamAndWaitForResult(kRenderId+1, kPageRequestId + 1, 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 label2 = host_->label_;
498   const std::string device_id2 = host_->video_devices_.front().device.id;
499   const int session_id2 = host_->video_devices_.front().session_id;
500   EXPECT_EQ(device_id1, device_id2);
501   EXPECT_NE(session_id1, session_id2);
502   EXPECT_NE(label1, label2);
503 }
504
505 // This test request two streams with video only without waiting for the first
506 // stream to be generated before requesting the second.
507 // The same device id and session ids are expected.
508 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithoutWaiting) {
509   StreamOptions options(false, true);
510
511   // Generate first stream.
512   SetupFakeUI(true);
513   EXPECT_CALL(*host_.get(), OnStreamGenerated(kRenderId, kPageRequestId, 0, 1));
514
515   // Generate second stream.
516   EXPECT_CALL(*host_.get(),
517               OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
518
519   base::RunLoop run_loop1;
520   base::RunLoop run_loop2;
521   host_->OnGenerateStream(kRenderId, kPageRequestId, options, origin_,
522                           run_loop1.QuitClosure());
523   host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
524                           run_loop2.QuitClosure());
525
526   run_loop1.Run();
527   run_loop2.Run();
528 }
529
530 // Test that we can generate streams where a mandatory sourceId is specified in
531 // the request.
532 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithMandatorySourceId) {
533   ASSERT_GE(physical_audio_devices_.size(), 1u);
534   ASSERT_GE(physical_video_devices_.size(), 1u);
535
536   media::AudioDeviceNames::const_iterator audio_it =
537       physical_audio_devices_.begin();
538   for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
539     std::string source_id = content::GetHMACForMediaDeviceID(
540         browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
541         origin_,
542         audio_it->unique_id);
543     ASSERT_FALSE(source_id.empty());
544     StreamOptions options(true, true);
545     AddSourceIdConstraint(source_id, &options.mandatory_audio);
546
547     SetupFakeUI(true);
548     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
549     EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
550   }
551
552   media::VideoCaptureDevice::Names::const_iterator video_it =
553       physical_video_devices_.begin();
554   for (; video_it != physical_video_devices_.end(); ++video_it) {
555     std::string source_id = content::GetHMACForMediaDeviceID(
556         browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
557         origin_,
558         video_it->id());
559     ASSERT_FALSE(source_id.empty());
560     StreamOptions options(true, true);
561     AddSourceIdConstraint(source_id, &options.mandatory_video);
562
563     SetupFakeUI(true);
564     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
565     EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
566   }
567 }
568
569 // Test that we can generate streams where a optional sourceId is specified in
570 // the request.
571 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsWithOptionalSourceId) {
572   ASSERT_GE(physical_audio_devices_.size(), 1u);
573   ASSERT_GE(physical_video_devices_.size(), 1u);
574
575   media::AudioDeviceNames::const_iterator audio_it =
576       physical_audio_devices_.begin();
577   for (; audio_it != physical_audio_devices_.end(); ++audio_it) {
578     std::string source_id = content::GetHMACForMediaDeviceID(
579         browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
580         origin_,
581         audio_it->unique_id);
582     ASSERT_FALSE(source_id.empty());
583     StreamOptions options(true, true);
584     AddSourceIdConstraint(source_id, &options.optional_audio);
585
586     SetupFakeUI(true);
587     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
588     EXPECT_EQ(host_->audio_devices_[0].device.id, source_id);
589   }
590
591   media::VideoCaptureDevice::Names::const_iterator video_it =
592       physical_video_devices_.begin();
593   for (; video_it != physical_video_devices_.end(); ++video_it) {
594     std::string source_id = content::GetHMACForMediaDeviceID(
595         browser_context_.GetResourceContext()->GetMediaDeviceIDSalt(),
596         origin_,
597         video_it->id());
598     ASSERT_FALSE(source_id.empty());
599     StreamOptions options(true, true);
600     AddSourceIdConstraint(source_id, &options.optional_video);
601
602     SetupFakeUI(true);
603     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
604     EXPECT_EQ(host_->video_devices_[0].device.id, source_id);
605   }
606 }
607
608 // Test that generating a stream with an invalid mandatory video source id fail.
609 TEST_F(MediaStreamDispatcherHostTest,
610        GenerateStreamsWithInvalidMandatoryVideoSourceId) {
611   StreamOptions options(true, true);
612   AddSourceIdConstraint("invalid source id", &options.mandatory_video);
613
614   GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options);
615 }
616
617 // Test that generating a stream with an invalid mandatory audio source id fail.
618 TEST_F(MediaStreamDispatcherHostTest,
619        GenerateStreamsWithInvalidMandatoryAudioSourceId) {
620   StreamOptions options(true, true);
621   AddSourceIdConstraint("invalid source id", &options.mandatory_audio);
622
623   GenerateStreamAndWaitForFailure(kRenderId, kPageRequestId, options);
624 }
625
626 // Test that generating a stream with an invalid optional video source id
627 // succeed.
628 TEST_F(MediaStreamDispatcherHostTest,
629        GenerateStreamsWithInvalidOptionalVideoSourceId) {
630   StreamOptions options(true, true);
631   AddSourceIdConstraint("invalid source id", &options.optional_video);
632
633   SetupFakeUI(true);
634   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
635 }
636
637 // Test that generating a stream with an invalid optional audio source id
638 // succeed.
639 TEST_F(MediaStreamDispatcherHostTest,
640        GenerateStreamsWithInvalidOptionalAudioSourceId) {
641   StreamOptions options(true, true);
642   AddSourceIdConstraint("invalid source id", &options.optional_audio);
643
644   SetupFakeUI(true);
645   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
646 }
647
648 TEST_F(MediaStreamDispatcherHostTest, GenerateStreamsNoAvailableVideoDevice) {
649   size_t number_of_fake_devices = physical_video_devices_.size();
650   media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(0);
651   media::FakeVideoCaptureDevice::GetDeviceNames(&physical_video_devices_);
652   StreamOptions options(true, true);
653
654   SetupFakeUI(true);
655   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
656   EXPECT_TRUE(host_->video_devices_.empty());
657
658   // Reset the number of fake devices for next test.
659   media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(number_of_fake_devices);
660 }
661
662 // Test that if a OnStopStreamDevice message is received for a device that has
663 // been opened in a MediaStream and by pepper, the device is only stopped for
664 // the MediaStream.
665 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStream) {
666   StreamOptions options(false, true);
667
668   SetupFakeUI(true);
669   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
670
671   std::string stream_request_label = host_->label_;
672   StreamDeviceInfo video_device_info = host_->video_devices_.front();
673   ASSERT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
674       stream_request_label).size());
675
676   // Open the same device by Pepper.
677   OpenVideoDeviceAndWaitForResult(kRenderId, kPageRequestId,
678                                   video_device_info.device.id);
679   std::string open_device_request_label = host_->label_;
680
681   // Stop the device in the MediaStream.
682   host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
683
684   EXPECT_EQ(0u, media_stream_manager_->GetDevicesOpenedByRequest(
685       stream_request_label).size());
686   EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
687       open_device_request_label).size());
688 }
689
690 TEST_F(MediaStreamDispatcherHostTest, StopDeviceInStreamAndRestart) {
691   StreamOptions options(true, true);
692
693   SetupFakeUI(true);
694   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
695
696   std::string request_label1 = host_->label_;
697   StreamDeviceInfo video_device_info = host_->video_devices_.front();
698   // Expect that 1 audio and 1 video device has been opened.
699   EXPECT_EQ(2u, media_stream_manager_->GetDevicesOpenedByRequest(
700       request_label1).size());
701
702   host_->OnStopStreamDevice(kRenderId, video_device_info.device.id);
703   EXPECT_EQ(1u, media_stream_manager_->GetDevicesOpenedByRequest(
704       request_label1).size());
705
706   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
707   std::string request_label2 = host_->label_;
708
709   StreamDeviceInfoArray request1_devices =
710       media_stream_manager_->GetDevicesOpenedByRequest(request_label1);
711   StreamDeviceInfoArray request2_devices =
712       media_stream_manager_->GetDevicesOpenedByRequest(request_label2);
713
714   ASSERT_EQ(1u, request1_devices.size());
715   ASSERT_EQ(2u, request2_devices.size());
716
717   // Test that the same audio device has been opened in both streams.
718   EXPECT_TRUE(StreamDeviceInfo::IsEqual(request1_devices[0],
719                                         request2_devices[0]) ||
720               StreamDeviceInfo::IsEqual(request1_devices[0],
721                                         request2_devices[1]));
722 }
723
724 TEST_F(MediaStreamDispatcherHostTest,
725        GenerateTwoStreamsAndStopDeviceWhileWaitingForSecondStream) {
726   StreamOptions options(false, true);
727
728   SetupFakeUI(true);
729   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
730   EXPECT_EQ(host_->video_devices_.size(), 1u);
731
732   // Generate a second stream.
733   EXPECT_CALL(*host_.get(),
734               OnStreamGenerated(kRenderId, kPageRequestId + 1, 0, 1));
735
736   base::RunLoop run_loop1;
737   host_->OnGenerateStream(kRenderId, kPageRequestId + 1, options, origin_,
738                           run_loop1.QuitClosure());
739
740   // Stop the video stream device from stream 1 while waiting for the
741   // second stream to be generated.
742   host_->OnStopStreamDevice(kRenderId, host_->video_devices_[0].device.id);
743   run_loop1.Run();
744
745   EXPECT_EQ(host_->video_devices_.size(), 1u);
746 }
747
748 TEST_F(MediaStreamDispatcherHostTest, CancelPendingStreamsOnChannelClosing) {
749   StreamOptions options(false, true);
750
751   base::RunLoop run_loop;
752
753   // Create multiple GenerateStream requests.
754   size_t streams = 5;
755   for (size_t i = 1; i <= streams; ++i) {
756     host_->OnGenerateStream(kRenderId, kPageRequestId + i, options, origin_,
757                             run_loop.QuitClosure());
758   }
759
760   // Calling OnChannelClosing() to cancel all the pending requests.
761   host_->OnChannelClosing();
762   run_loop.RunUntilIdle();
763 }
764
765 TEST_F(MediaStreamDispatcherHostTest, StopGeneratedStreamsOnChannelClosing) {
766   StreamOptions options(false, true);
767
768   // Create first group of streams.
769   size_t generated_streams = 3;
770   for (size_t i = 0; i < generated_streams; ++i) {
771     SetupFakeUI(true);
772     GenerateStreamAndWaitForResult(kRenderId, kPageRequestId + i, options);
773   }
774
775   // Calling OnChannelClosing() to cancel all the pending/generated streams.
776   host_->OnChannelClosing();
777   base::RunLoop().RunUntilIdle();
778 }
779
780 TEST_F(MediaStreamDispatcherHostTest, CloseFromUI) {
781   StreamOptions options(false, true);
782
783   base::Closure close_callback;
784   scoped_ptr<MockMediaStreamUIProxy> stream_ui(new MockMediaStreamUIProxy());
785   EXPECT_CALL(*stream_ui, OnStarted(_))
786       .WillOnce(SaveArg<0>(&close_callback));
787   media_stream_manager_->UseFakeUI(stream_ui.PassAs<FakeMediaStreamUIProxy>());
788
789   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
790
791   EXPECT_EQ(host_->audio_devices_.size(), 0u);
792   EXPECT_EQ(host_->video_devices_.size(), 1u);
793
794   ASSERT_FALSE(close_callback.is_null());
795   EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId));
796   close_callback.Run();
797   base::RunLoop().RunUntilIdle();
798 }
799
800 // Test that the dispatcher is notified if a video device that is in use is
801 // being unplugged.
802 TEST_F(MediaStreamDispatcherHostTest, VideoDeviceUnplugged) {
803   size_t number_of_fake_devices = physical_video_devices_.size();
804   StreamOptions options(true, true);
805   SetupFakeUI(true);
806   GenerateStreamAndWaitForResult(kRenderId, kPageRequestId, options);
807   EXPECT_EQ(host_->audio_devices_.size(), 1u);
808   EXPECT_EQ(host_->video_devices_.size(), 1u);
809
810   media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(0);
811
812   base::RunLoop run_loop;
813   EXPECT_CALL(*host_.get(), OnDeviceStopped(kRenderId))
814       .WillOnce(testing::InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
815   media_stream_manager_->OnDevicesChanged(
816       base::SystemMonitor::DEVTYPE_VIDEO_CAPTURE);
817
818   run_loop.Run();
819
820   media::FakeVideoCaptureDevice::SetNumberOfFakeDevices(number_of_fake_devices);
821 }
822
823 TEST_F(MediaStreamDispatcherHostTest, EnumerateAudioDevices) {
824   EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
825                                    MEDIA_DEVICE_AUDIO_CAPTURE);
826 }
827
828 TEST_F(MediaStreamDispatcherHostTest, EnumerateVideoDevices) {
829   EnumerateDevicesAndWaitForResult(kRenderId, kPageRequestId,
830                                    MEDIA_DEVICE_VIDEO_CAPTURE);
831 }
832
833 };  // namespace content