Home | History | Annotate | Download | only in media
      1 // Copyright 2013 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 "base/strings/string_number_conversions.h"
      6 #include "content/browser/renderer_host/media/device_request_message_filter.h"
      7 #include "content/browser/renderer_host/media/media_stream_manager.h"
      8 #include "content/common/media/media_stream_messages.h"
      9 #include "content/public/test/mock_resource_context.h"
     10 #include "content/public/test/test_browser_thread.h"
     11 #include "testing/gmock/include/gmock/gmock.h"
     12 #include "testing/gtest/include/gtest/gtest.h"
     13 
     14 using ::testing::_;
     15 using ::testing::Invoke;
     16 
     17 namespace content {
     18 
     19 static const std::string kAudioLabel = "audio_label";
     20 static const std::string kVideoLabel = "video_label";
     21 
     22 class MockMediaStreamManager : public MediaStreamManager {
     23  public:
     24   MockMediaStreamManager() {}
     25 
     26   virtual ~MockMediaStreamManager() {}
     27 
     28   MOCK_METHOD7(EnumerateDevices,
     29                std::string(MediaStreamRequester* requester,
     30                            int render_process_id,
     31                            int render_frame_id,
     32                            const ResourceContext::SaltCallback& rc,
     33                            int page_request_id,
     34                            MediaStreamType type,
     35                            const GURL& security_origin));
     36 
     37   std::string DoEnumerateDevices(MediaStreamRequester* requester,
     38                                  int render_process_id,
     39                                  int render_frame_id,
     40                                  const ResourceContext::SaltCallback& rc,
     41                                  int page_request_id,
     42                                  MediaStreamType type,
     43                                  const GURL& security_origin) {
     44     if (type == MEDIA_DEVICE_AUDIO_CAPTURE) {
     45       return kAudioLabel;
     46     } else {
     47       return kVideoLabel;
     48     }
     49   }
     50 };
     51 
     52 class MockDeviceRequestMessageFilter : public DeviceRequestMessageFilter {
     53  public:
     54   MockDeviceRequestMessageFilter(MockResourceContext* context,
     55                                  MockMediaStreamManager* manager)
     56       : DeviceRequestMessageFilter(context, manager, 0), received_id_(-1) {}
     57   StreamDeviceInfoArray requested_devices() { return requested_devices_; }
     58   int received_id() { return received_id_; }
     59 
     60  private:
     61   virtual ~MockDeviceRequestMessageFilter() {}
     62 
     63   // Override the Send() method to intercept the message that we're sending to
     64   // the renderer.
     65   virtual bool Send(IPC::Message* reply_msg) OVERRIDE {
     66     CHECK(reply_msg);
     67 
     68     bool handled = true;
     69     IPC_BEGIN_MESSAGE_MAP(MockDeviceRequestMessageFilter, *reply_msg)
     70       IPC_MESSAGE_HANDLER(MediaStreamMsg_GetSourcesACK, SaveDevices)
     71       IPC_MESSAGE_UNHANDLED(handled = false)
     72     IPC_END_MESSAGE_MAP()
     73     EXPECT_TRUE(handled);
     74 
     75     delete reply_msg;
     76     return true;
     77   }
     78 
     79   void SaveDevices(int request_id, const StreamDeviceInfoArray& devices) {
     80     received_id_ = request_id;
     81     requested_devices_ = devices;
     82   }
     83 
     84   int received_id_;
     85   StreamDeviceInfoArray requested_devices_;
     86 };
     87 
     88 class DeviceRequestMessageFilterTest : public testing::Test {
     89  public:
     90   DeviceRequestMessageFilterTest() : next_device_id_(0) {}
     91 
     92   void RunTest(int number_audio_devices, int number_video_devices) {
     93     AddAudioDevices(number_audio_devices);
     94     AddVideoDevices(number_video_devices);
     95     GURL origin("https://test.com");
     96     EXPECT_CALL(*media_stream_manager_,
     97                 EnumerateDevices(_, _, _, _, _, MEDIA_DEVICE_AUDIO_CAPTURE,
     98                                  _))
     99         .Times(1);
    100     EXPECT_CALL(*media_stream_manager_,
    101                 EnumerateDevices(_, _, _, _, _, MEDIA_DEVICE_VIDEO_CAPTURE,
    102                                  _))
    103         .Times(1);
    104     // Send message to get devices. Should trigger 2 EnumerateDevice() requests.
    105     const int kRequestId = 123;
    106     SendGetSourcesMessage(kRequestId, origin);
    107 
    108     // Run audio callback. Because there's still an outstanding video request,
    109     // this should not populate |message|.
    110     FireAudioDeviceCallback();
    111     EXPECT_EQ(0u, host_->requested_devices().size());
    112 
    113     // After the video device callback is fired, |message| should be populated.
    114     FireVideoDeviceCallback();
    115     EXPECT_EQ(static_cast<size_t>(number_audio_devices + number_video_devices),
    116               host_->requested_devices().size());
    117 
    118     EXPECT_EQ(kRequestId, host_->received_id());
    119   }
    120 
    121  protected:
    122   virtual ~DeviceRequestMessageFilterTest() {}
    123 
    124   virtual void SetUp() OVERRIDE {
    125     message_loop_.reset(new base::MessageLoopForIO);
    126     io_thread_.reset(
    127         new TestBrowserThread(BrowserThread::IO, message_loop_.get()));
    128 
    129     media_stream_manager_.reset(new MockMediaStreamManager());
    130     ON_CALL(*media_stream_manager_, EnumerateDevices(_, _, _, _, _, _, _))
    131         .WillByDefault(Invoke(media_stream_manager_.get(),
    132                               &MockMediaStreamManager::DoEnumerateDevices));
    133 
    134     resource_context_.reset(new MockResourceContext(NULL));
    135     host_ = new MockDeviceRequestMessageFilter(resource_context_.get(),
    136                                                media_stream_manager_.get());
    137   }
    138 
    139   scoped_refptr<MockDeviceRequestMessageFilter> host_;
    140   scoped_ptr<MockMediaStreamManager> media_stream_manager_;
    141   scoped_ptr<MockResourceContext> resource_context_;
    142   StreamDeviceInfoArray physical_audio_devices_;
    143   StreamDeviceInfoArray physical_video_devices_;
    144   scoped_ptr<base::MessageLoop> message_loop_;
    145   scoped_ptr<TestBrowserThread> io_thread_;
    146 
    147  private:
    148   void AddAudioDevices(int number_of_devices) {
    149     for (int i = 0; i < number_of_devices; i++) {
    150       physical_audio_devices_.push_back(
    151           StreamDeviceInfo(
    152               MEDIA_DEVICE_AUDIO_CAPTURE,
    153               "/dev/audio/" + base::IntToString(next_device_id_),
    154               "Audio Device" + base::IntToString(next_device_id_)));
    155       next_device_id_++;
    156     }
    157   }
    158 
    159   void AddVideoDevices(int number_of_devices) {
    160     for (int i = 0; i < number_of_devices; i++) {
    161       physical_video_devices_.push_back(
    162           StreamDeviceInfo(
    163               MEDIA_DEVICE_VIDEO_CAPTURE,
    164               "/dev/video/" + base::IntToString(next_device_id_),
    165               "Video Device" + base::IntToString(next_device_id_)));
    166       next_device_id_++;
    167     }
    168   }
    169 
    170   void SendGetSourcesMessage(int request_id, const GURL& origin) {
    171     host_->OnMessageReceived(MediaStreamHostMsg_GetSources(request_id, origin));
    172   }
    173 
    174   void FireAudioDeviceCallback() {
    175     host_->DevicesEnumerated(-1, -1, kAudioLabel, physical_audio_devices_);
    176   }
    177 
    178   void FireVideoDeviceCallback() {
    179     host_->DevicesEnumerated(-1, -1, kVideoLabel, physical_video_devices_);
    180   }
    181 
    182   int next_device_id_;
    183 };
    184 
    185 TEST_F(DeviceRequestMessageFilterTest, TestGetSources_AudioAndVideoDevices) {
    186   // Runs through test with 1 audio and 1 video device.
    187   RunTest(1, 1);
    188 }
    189 
    190 TEST_F(DeviceRequestMessageFilterTest,
    191        TestGetSources_MultipleAudioAndVideoDevices) {
    192   // Runs through test with 3 audio devices and 2 video devices.
    193   RunTest(3, 2);
    194 }
    195 
    196 TEST_F(DeviceRequestMessageFilterTest, TestGetSources_NoVideoDevices) {
    197   // Runs through test with 4 audio devices and 0 video devices.
    198   RunTest(4, 0);
    199 }
    200 
    201 TEST_F(DeviceRequestMessageFilterTest, TestGetSources_NoAudioDevices) {
    202   // Runs through test with 0 audio devices and 3 video devices.
    203   RunTest(0, 3);
    204 }
    205 
    206 TEST_F(DeviceRequestMessageFilterTest, TestGetSources_NoDevices) {
    207   // Runs through test with no devices.
    208   RunTest(0, 0);
    209 }
    210 
    211 };  // namespace content
    212