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 "content/browser/renderer_host/media/media_stream_ui_proxy.h"
      6 
      7 #include "base/message_loop/message_loop.h"
      8 #include "content/browser/frame_host/render_frame_host_delegate.h"
      9 #include "content/public/common/renderer_preferences.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 #include "ui/gfx/rect.h"
     14 
     15 using testing::_;
     16 using testing::Return;
     17 using testing::SaveArg;
     18 
     19 namespace content {
     20 namespace {
     21 
     22 class MockRenderFrameHostDelegate : public RenderFrameHostDelegate {
     23  public:
     24   MOCK_METHOD2(RequestMediaAccessPermission,
     25                void(const MediaStreamRequest& request,
     26                     const MediaResponseCallback& callback));
     27   MOCK_METHOD2(CheckMediaAccessPermission,
     28                bool(const GURL& security_origin,
     29                     MediaStreamType type));
     30 };
     31 
     32 class MockResponseCallback {
     33  public:
     34   MOCK_METHOD2(OnAccessRequestResponse,
     35                void(const MediaStreamDevices& devices,
     36                content::MediaStreamRequestResult result));
     37   MOCK_METHOD1(OnCheckResponse, void(bool have_access));
     38 };
     39 
     40 class MockMediaStreamUI : public MediaStreamUI {
     41  public:
     42   MOCK_METHOD1(OnStarted, gfx::NativeViewId(const base::Closure& stop));
     43 };
     44 
     45 class MockStopStreamHandler {
     46  public:
     47   MOCK_METHOD0(OnStop, void());
     48   MOCK_METHOD1(OnWindowId, void(gfx::NativeViewId window_id));
     49 };
     50 
     51 
     52 }  // namespace
     53 
     54 class MediaStreamUIProxyTest : public testing::Test {
     55  public:
     56   MediaStreamUIProxyTest()
     57       : ui_thread_(BrowserThread::UI, &message_loop_),
     58         io_thread_(BrowserThread::IO, &message_loop_) {
     59     proxy_ = MediaStreamUIProxy::CreateForTests(&delegate_);
     60   }
     61 
     62   virtual ~MediaStreamUIProxyTest() {
     63     proxy_.reset();
     64     message_loop_.RunUntilIdle();
     65   }
     66 
     67  protected:
     68   base::MessageLoop message_loop_;
     69   TestBrowserThread ui_thread_;
     70   TestBrowserThread io_thread_;
     71 
     72   MockRenderFrameHostDelegate delegate_;
     73   MockResponseCallback response_callback_;
     74   scoped_ptr<MediaStreamUIProxy> proxy_;
     75 };
     76 
     77 MATCHER_P(SameRequest, expected, "") {
     78   return
     79     expected.render_process_id == arg.render_process_id &&
     80     expected.render_frame_id == arg.render_frame_id &&
     81     expected.tab_capture_device_id == arg.tab_capture_device_id &&
     82     expected.security_origin == arg.security_origin &&
     83     expected.request_type == arg.request_type &&
     84     expected.requested_audio_device_id == arg.requested_audio_device_id &&
     85     expected.requested_video_device_id == arg.requested_video_device_id &&
     86     expected.audio_type == arg.audio_type &&
     87     expected.video_type == arg.video_type;
     88 }
     89 
     90 TEST_F(MediaStreamUIProxyTest, Deny) {
     91   MediaStreamRequest request(0, 0, 0, GURL("http://origin/"), false,
     92                              MEDIA_GENERATE_STREAM, std::string(),
     93                              std::string(),
     94                              MEDIA_DEVICE_AUDIO_CAPTURE,
     95                              MEDIA_DEVICE_VIDEO_CAPTURE);
     96   proxy_->RequestAccess(
     97       request, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
     98                           base::Unretained(&response_callback_)));
     99   MediaResponseCallback callback;
    100   EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
    101     .WillOnce(SaveArg<1>(&callback));
    102   message_loop_.RunUntilIdle();
    103   ASSERT_FALSE(callback.is_null());
    104 
    105   MediaStreamDevices devices;
    106   callback.Run(devices, MEDIA_DEVICE_OK, scoped_ptr<MediaStreamUI>());
    107 
    108   MediaStreamDevices response;
    109   EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
    110     .WillOnce(SaveArg<0>(&response));
    111   message_loop_.RunUntilIdle();
    112 
    113   EXPECT_TRUE(response.empty());
    114 }
    115 
    116 TEST_F(MediaStreamUIProxyTest, AcceptAndStart) {
    117   MediaStreamRequest request(0, 0, 0, GURL("http://origin/"), false,
    118                              MEDIA_GENERATE_STREAM, std::string(),
    119                              std::string(),
    120                              MEDIA_DEVICE_AUDIO_CAPTURE,
    121                              MEDIA_DEVICE_VIDEO_CAPTURE);
    122   proxy_->RequestAccess(
    123       request, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
    124                           base::Unretained(&response_callback_)));
    125   MediaResponseCallback callback;
    126   EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
    127     .WillOnce(SaveArg<1>(&callback));
    128   message_loop_.RunUntilIdle();
    129   ASSERT_FALSE(callback.is_null());
    130 
    131   MediaStreamDevices devices;
    132   devices.push_back(
    133       MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
    134   scoped_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
    135   EXPECT_CALL(*ui, OnStarted(_)).WillOnce(Return(0));
    136   callback.Run(devices, MEDIA_DEVICE_OK, ui.PassAs<MediaStreamUI>());
    137 
    138   MediaStreamDevices response;
    139   EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
    140     .WillOnce(SaveArg<0>(&response));
    141   message_loop_.RunUntilIdle();
    142 
    143   EXPECT_FALSE(response.empty());
    144 
    145   proxy_->OnStarted(base::Closure(), MediaStreamUIProxy::WindowIdCallback());
    146   message_loop_.RunUntilIdle();
    147 }
    148 
    149 // Verify that the proxy can be deleted before the request is processed.
    150 TEST_F(MediaStreamUIProxyTest, DeleteBeforeAccepted) {
    151   MediaStreamRequest request(0, 0, 0, GURL("http://origin/"), false,
    152                              MEDIA_GENERATE_STREAM, std::string(),
    153                              std::string(),
    154                              MEDIA_DEVICE_AUDIO_CAPTURE,
    155                              MEDIA_DEVICE_VIDEO_CAPTURE);
    156   proxy_->RequestAccess(
    157       request, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
    158                           base::Unretained(&response_callback_)));
    159   MediaResponseCallback callback;
    160   EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
    161     .WillOnce(SaveArg<1>(&callback));
    162   message_loop_.RunUntilIdle();
    163   ASSERT_FALSE(callback.is_null());
    164 
    165   proxy_.reset();
    166 
    167   MediaStreamDevices devices;
    168   scoped_ptr<MediaStreamUI> ui;
    169   callback.Run(devices, MEDIA_DEVICE_OK, ui.Pass());
    170 }
    171 
    172 TEST_F(MediaStreamUIProxyTest, StopFromUI) {
    173   MediaStreamRequest request(0, 0, 0, GURL("http://origin/"), false,
    174                              MEDIA_GENERATE_STREAM, std::string(),
    175                              std::string(),
    176                              MEDIA_DEVICE_AUDIO_CAPTURE,
    177                              MEDIA_DEVICE_VIDEO_CAPTURE);
    178   proxy_->RequestAccess(
    179       request, base::Bind(&MockResponseCallback::OnAccessRequestResponse,
    180                           base::Unretained(&response_callback_)));
    181   MediaResponseCallback callback;
    182   EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
    183     .WillOnce(SaveArg<1>(&callback));
    184   message_loop_.RunUntilIdle();
    185   ASSERT_FALSE(callback.is_null());
    186 
    187   base::Closure stop_callback;
    188 
    189   MediaStreamDevices devices;
    190   devices.push_back(
    191       MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE, "Mic", "Mic"));
    192   scoped_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
    193   EXPECT_CALL(*ui, OnStarted(_))
    194       .WillOnce(testing::DoAll(SaveArg<0>(&stop_callback), Return(0)));
    195   callback.Run(devices, MEDIA_DEVICE_OK, ui.PassAs<MediaStreamUI>());
    196 
    197   MediaStreamDevices response;
    198   EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _))
    199     .WillOnce(SaveArg<0>(&response));
    200   message_loop_.RunUntilIdle();
    201 
    202   EXPECT_FALSE(response.empty());
    203 
    204   MockStopStreamHandler stop_handler;
    205   proxy_->OnStarted(base::Bind(&MockStopStreamHandler::OnStop,
    206                                base::Unretained(&stop_handler)),
    207                     MediaStreamUIProxy::WindowIdCallback());
    208   message_loop_.RunUntilIdle();
    209 
    210   ASSERT_FALSE(stop_callback.is_null());
    211   EXPECT_CALL(stop_handler, OnStop());
    212   stop_callback.Run();
    213   message_loop_.RunUntilIdle();
    214 }
    215 
    216 TEST_F(MediaStreamUIProxyTest, WindowIdCallbackCalled) {
    217   MediaStreamRequest request(0,
    218                              0,
    219                              0,
    220                              GURL("http://origin/"),
    221                              false,
    222                              MEDIA_GENERATE_STREAM,
    223                              std::string(),
    224                              std::string(),
    225                              MEDIA_NO_SERVICE,
    226                              MEDIA_DESKTOP_VIDEO_CAPTURE);
    227   proxy_->RequestAccess(
    228       request,
    229       base::Bind(&MockResponseCallback::OnAccessRequestResponse,
    230                  base::Unretained(&response_callback_)));
    231   MediaResponseCallback callback;
    232   EXPECT_CALL(delegate_, RequestMediaAccessPermission(SameRequest(request), _))
    233       .WillOnce(SaveArg<1>(&callback));
    234   message_loop_.RunUntilIdle();
    235 
    236   const int kWindowId = 1;
    237   scoped_ptr<MockMediaStreamUI> ui(new MockMediaStreamUI());
    238   EXPECT_CALL(*ui, OnStarted(_)).WillOnce(Return(kWindowId));
    239 
    240   callback.Run(
    241       MediaStreamDevices(), MEDIA_DEVICE_OK, ui.PassAs<MediaStreamUI>());
    242   EXPECT_CALL(response_callback_, OnAccessRequestResponse(_, _));
    243 
    244   MockStopStreamHandler handler;
    245   EXPECT_CALL(handler, OnWindowId(kWindowId));
    246 
    247   proxy_->OnStarted(
    248       base::Bind(&MockStopStreamHandler::OnStop, base::Unretained(&handler)),
    249       base::Bind(&MockStopStreamHandler::OnWindowId,
    250                  base::Unretained(&handler)));
    251   message_loop_.RunUntilIdle();
    252 }
    253 
    254 TEST_F(MediaStreamUIProxyTest, CheckAccess) {
    255   proxy_->CheckAccess(GURL("http://origin/"),
    256                            MEDIA_DEVICE_AUDIO_CAPTURE,
    257                            0,
    258                            0,
    259                            base::Bind(&MockResponseCallback::OnCheckResponse,
    260                                       base::Unretained(&response_callback_)));
    261   EXPECT_CALL(delegate_, CheckMediaAccessPermission(_, _));
    262   EXPECT_CALL(response_callback_, OnCheckResponse(_));
    263   message_loop_.RunUntilIdle();
    264 }
    265 
    266 }  // content
    267