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.
5 #include "content/browser/renderer_host/media/media_stream_ui_proxy.h"
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/geometry/rect.h"
16 using testing::Return
;
17 using testing::SaveArg
;
22 class MockRenderFrameHostDelegate
: public RenderFrameHostDelegate
{
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
));
32 class MockResponseCallback
{
34 MOCK_METHOD2(OnAccessRequestResponse
,
35 void(const MediaStreamDevices
& devices
,
36 content::MediaStreamRequestResult result
));
37 MOCK_METHOD1(OnCheckResponse
, void(bool have_access
));
40 class MockMediaStreamUI
: public MediaStreamUI
{
42 MOCK_METHOD1(OnStarted
, gfx::NativeViewId(const base::Closure
& stop
));
45 class MockStopStreamHandler
{
47 MOCK_METHOD0(OnStop
, void());
48 MOCK_METHOD1(OnWindowId
, void(gfx::NativeViewId window_id
));
54 class MediaStreamUIProxyTest
: public testing::Test
{
56 MediaStreamUIProxyTest()
57 : ui_thread_(BrowserThread::UI
, &message_loop_
),
58 io_thread_(BrowserThread::IO
, &message_loop_
) {
59 proxy_
= MediaStreamUIProxy::CreateForTests(&delegate_
);
62 ~MediaStreamUIProxyTest() override
{
64 message_loop_
.RunUntilIdle();
68 base::MessageLoop message_loop_
;
69 TestBrowserThread ui_thread_
;
70 TestBrowserThread io_thread_
;
72 MockRenderFrameHostDelegate delegate_
;
73 MockResponseCallback response_callback_
;
74 scoped_ptr
<MediaStreamUIProxy
> proxy_
;
77 MATCHER_P(SameRequest
, expected
, "") {
79 expected
->render_process_id
== arg
.render_process_id
&&
80 expected
->render_frame_id
== arg
.render_frame_id
&&
81 expected
->security_origin
== arg
.security_origin
&&
82 expected
->request_type
== arg
.request_type
&&
83 expected
->requested_audio_device_id
== arg
.requested_audio_device_id
&&
84 expected
->requested_video_device_id
== arg
.requested_video_device_id
&&
85 expected
->audio_type
== arg
.audio_type
&&
86 expected
->video_type
== arg
.video_type
;
89 TEST_F(MediaStreamUIProxyTest
, Deny
) {
90 scoped_ptr
<MediaStreamRequest
> request (
91 new MediaStreamRequest(0, 0, 0, GURL("http://origin/"),
93 MEDIA_GENERATE_STREAM
, std::string(),
95 MEDIA_DEVICE_AUDIO_CAPTURE
,
96 MEDIA_DEVICE_VIDEO_CAPTURE
));
97 MediaStreamRequest
* request_ptr
= request
.get();
98 proxy_
->RequestAccess(
99 request
.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
100 base::Unretained(&response_callback_
)));
101 MediaResponseCallback callback
;
102 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
),
104 .WillOnce(SaveArg
<1>(&callback
));
105 message_loop_
.RunUntilIdle();
106 ASSERT_FALSE(callback
.is_null());
108 MediaStreamDevices devices
;
109 callback
.Run(devices
, MEDIA_DEVICE_OK
, scoped_ptr
<MediaStreamUI
>());
111 MediaStreamDevices response
;
112 EXPECT_CALL(response_callback_
, OnAccessRequestResponse(_
, _
))
113 .WillOnce(SaveArg
<0>(&response
));
114 message_loop_
.RunUntilIdle();
116 EXPECT_TRUE(response
.empty());
119 TEST_F(MediaStreamUIProxyTest
, AcceptAndStart
) {
120 scoped_ptr
<MediaStreamRequest
> request (
121 new MediaStreamRequest(0, 0, 0,
122 GURL("http://origin/"), false,
123 MEDIA_GENERATE_STREAM
, std::string(),
125 MEDIA_DEVICE_AUDIO_CAPTURE
,
126 MEDIA_DEVICE_VIDEO_CAPTURE
));
127 MediaStreamRequest
* request_ptr
= request
.get();
128 proxy_
->RequestAccess(
129 request
.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
130 base::Unretained(&response_callback_
)));
131 MediaResponseCallback callback
;
132 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
),
134 .WillOnce(SaveArg
<1>(&callback
));
135 message_loop_
.RunUntilIdle();
136 ASSERT_FALSE(callback
.is_null());
138 MediaStreamDevices devices
;
140 MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE
, "Mic", "Mic"));
141 scoped_ptr
<MockMediaStreamUI
> ui(new MockMediaStreamUI());
142 EXPECT_CALL(*ui
, OnStarted(_
)).WillOnce(Return(0));
143 callback
.Run(devices
, MEDIA_DEVICE_OK
, ui
.Pass());
145 MediaStreamDevices response
;
146 EXPECT_CALL(response_callback_
, OnAccessRequestResponse(_
, _
))
147 .WillOnce(SaveArg
<0>(&response
));
148 message_loop_
.RunUntilIdle();
150 EXPECT_FALSE(response
.empty());
152 proxy_
->OnStarted(base::Closure(), MediaStreamUIProxy::WindowIdCallback());
153 message_loop_
.RunUntilIdle();
156 // Verify that the proxy can be deleted before the request is processed.
157 TEST_F(MediaStreamUIProxyTest
, DeleteBeforeAccepted
) {
158 scoped_ptr
<MediaStreamRequest
> request (
159 new MediaStreamRequest(0, 0, 0,
160 GURL("http://origin/"), false,
161 MEDIA_GENERATE_STREAM
, std::string(),
163 MEDIA_DEVICE_AUDIO_CAPTURE
,
164 MEDIA_DEVICE_VIDEO_CAPTURE
));
165 MediaStreamRequest
* request_ptr
= request
.get();
166 proxy_
->RequestAccess(
167 request
.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
168 base::Unretained(&response_callback_
)));
169 MediaResponseCallback callback
;
170 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
)
172 .WillOnce(SaveArg
<1>(&callback
));
173 message_loop_
.RunUntilIdle();
174 ASSERT_FALSE(callback
.is_null());
178 MediaStreamDevices devices
;
179 scoped_ptr
<MediaStreamUI
> ui
;
180 callback
.Run(devices
, MEDIA_DEVICE_OK
, ui
.Pass());
183 TEST_F(MediaStreamUIProxyTest
, StopFromUI
) {
184 scoped_ptr
<MediaStreamRequest
> request (
185 new MediaStreamRequest(0, 0, 0,
186 GURL("http://origin/"), false,
187 MEDIA_GENERATE_STREAM
, std::string(),
189 MEDIA_DEVICE_AUDIO_CAPTURE
,
190 MEDIA_DEVICE_VIDEO_CAPTURE
));
191 MediaStreamRequest
* request_ptr
= request
.get();
192 proxy_
->RequestAccess(
193 request
.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
194 base::Unretained(&response_callback_
)));
195 MediaResponseCallback callback
;
196 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
)
198 .WillOnce(SaveArg
<1>(&callback
));
199 message_loop_
.RunUntilIdle();
200 ASSERT_FALSE(callback
.is_null());
202 base::Closure stop_callback
;
204 MediaStreamDevices devices
;
206 MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE
, "Mic", "Mic"));
207 scoped_ptr
<MockMediaStreamUI
> ui(new MockMediaStreamUI());
208 EXPECT_CALL(*ui
, OnStarted(_
))
209 .WillOnce(testing::DoAll(SaveArg
<0>(&stop_callback
), Return(0)));
210 callback
.Run(devices
, MEDIA_DEVICE_OK
, ui
.Pass());
212 MediaStreamDevices response
;
213 EXPECT_CALL(response_callback_
, OnAccessRequestResponse(_
, _
))
214 .WillOnce(SaveArg
<0>(&response
));
215 message_loop_
.RunUntilIdle();
217 EXPECT_FALSE(response
.empty());
219 MockStopStreamHandler stop_handler
;
220 proxy_
->OnStarted(base::Bind(&MockStopStreamHandler::OnStop
,
221 base::Unretained(&stop_handler
)),
222 MediaStreamUIProxy::WindowIdCallback());
223 message_loop_
.RunUntilIdle();
225 ASSERT_FALSE(stop_callback
.is_null());
226 EXPECT_CALL(stop_handler
, OnStop());
228 message_loop_
.RunUntilIdle();
231 TEST_F(MediaStreamUIProxyTest
, WindowIdCallbackCalled
) {
232 scoped_ptr
<MediaStreamRequest
> request (
233 new MediaStreamRequest(0, 0, 0,
234 GURL("http://origin/"), false,
235 MEDIA_GENERATE_STREAM
, std::string(),
238 MEDIA_DESKTOP_VIDEO_CAPTURE
));
239 MediaStreamRequest
* request_ptr
= request
.get();
241 proxy_
->RequestAccess(
243 base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
244 base::Unretained(&response_callback_
)));
245 MediaResponseCallback callback
;
246 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
),
248 .WillOnce(SaveArg
<1>(&callback
));
249 message_loop_
.RunUntilIdle();
251 const int kWindowId
= 1;
252 scoped_ptr
<MockMediaStreamUI
> ui(new MockMediaStreamUI());
253 EXPECT_CALL(*ui
, OnStarted(_
)).WillOnce(Return(kWindowId
));
255 callback
.Run(MediaStreamDevices(), MEDIA_DEVICE_OK
, ui
.Pass());
256 EXPECT_CALL(response_callback_
, OnAccessRequestResponse(_
, _
));
258 MockStopStreamHandler handler
;
259 EXPECT_CALL(handler
, OnWindowId(kWindowId
));
262 base::Bind(&MockStopStreamHandler::OnStop
, base::Unretained(&handler
)),
263 base::Bind(&MockStopStreamHandler::OnWindowId
,
264 base::Unretained(&handler
)));
265 message_loop_
.RunUntilIdle();
268 TEST_F(MediaStreamUIProxyTest
, CheckAccess
) {
269 proxy_
->CheckAccess(GURL("http://origin/"),
270 MEDIA_DEVICE_AUDIO_CAPTURE
,
273 base::Bind(&MockResponseCallback::OnCheckResponse
,
274 base::Unretained(&response_callback_
)));
275 EXPECT_CALL(delegate_
, CheckMediaAccessPermission(_
, _
));
276 EXPECT_CALL(response_callback_
, OnCheckResponse(_
));
277 message_loop_
.RunUntilIdle();