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/test/test_browser_thread.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/gfx/geometry/rect.h"
15 using testing::Return
;
16 using testing::SaveArg
;
21 class MockRenderFrameHostDelegate
: public RenderFrameHostDelegate
{
23 MOCK_METHOD2(RequestMediaAccessPermission
,
24 void(const MediaStreamRequest
& request
,
25 const MediaResponseCallback
& callback
));
26 MOCK_METHOD2(CheckMediaAccessPermission
,
27 bool(const GURL
& security_origin
,
28 MediaStreamType type
));
31 class MockResponseCallback
{
33 MOCK_METHOD2(OnAccessRequestResponse
,
34 void(const MediaStreamDevices
& devices
,
35 content::MediaStreamRequestResult result
));
36 MOCK_METHOD1(OnCheckResponse
, void(bool have_access
));
39 class MockMediaStreamUI
: public MediaStreamUI
{
41 MOCK_METHOD1(OnStarted
, gfx::NativeViewId(const base::Closure
& stop
));
44 class MockStopStreamHandler
{
46 MOCK_METHOD0(OnStop
, void());
47 MOCK_METHOD1(OnWindowId
, void(gfx::NativeViewId window_id
));
53 class MediaStreamUIProxyTest
: public testing::Test
{
55 MediaStreamUIProxyTest()
56 : ui_thread_(BrowserThread::UI
, &message_loop_
),
57 io_thread_(BrowserThread::IO
, &message_loop_
) {
58 proxy_
= MediaStreamUIProxy::CreateForTests(&delegate_
);
61 ~MediaStreamUIProxyTest() override
{
63 message_loop_
.RunUntilIdle();
67 base::MessageLoop message_loop_
;
68 TestBrowserThread ui_thread_
;
69 TestBrowserThread io_thread_
;
71 MockRenderFrameHostDelegate delegate_
;
72 MockResponseCallback response_callback_
;
73 scoped_ptr
<MediaStreamUIProxy
> proxy_
;
76 MATCHER_P(SameRequest
, expected
, "") {
78 expected
->render_process_id
== arg
.render_process_id
&&
79 expected
->render_frame_id
== arg
.render_frame_id
&&
80 expected
->security_origin
== arg
.security_origin
&&
81 expected
->request_type
== arg
.request_type
&&
82 expected
->requested_audio_device_id
== arg
.requested_audio_device_id
&&
83 expected
->requested_video_device_id
== arg
.requested_video_device_id
&&
84 expected
->audio_type
== arg
.audio_type
&&
85 expected
->video_type
== arg
.video_type
;
88 TEST_F(MediaStreamUIProxyTest
, Deny
) {
89 scoped_ptr
<MediaStreamRequest
> request (
90 new MediaStreamRequest(0, 0, 0, GURL("http://origin/"),
92 MEDIA_GENERATE_STREAM
, std::string(),
94 MEDIA_DEVICE_AUDIO_CAPTURE
,
95 MEDIA_DEVICE_VIDEO_CAPTURE
));
96 MediaStreamRequest
* request_ptr
= request
.get();
97 proxy_
->RequestAccess(
98 request
.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
99 base::Unretained(&response_callback_
)));
100 MediaResponseCallback callback
;
101 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
),
103 .WillOnce(SaveArg
<1>(&callback
));
104 message_loop_
.RunUntilIdle();
105 ASSERT_FALSE(callback
.is_null());
107 MediaStreamDevices devices
;
108 callback
.Run(devices
, MEDIA_DEVICE_OK
, scoped_ptr
<MediaStreamUI
>());
110 MediaStreamDevices response
;
111 EXPECT_CALL(response_callback_
, OnAccessRequestResponse(_
, _
))
112 .WillOnce(SaveArg
<0>(&response
));
113 message_loop_
.RunUntilIdle();
115 EXPECT_TRUE(response
.empty());
118 TEST_F(MediaStreamUIProxyTest
, AcceptAndStart
) {
119 scoped_ptr
<MediaStreamRequest
> request (
120 new MediaStreamRequest(0, 0, 0,
121 GURL("http://origin/"), false,
122 MEDIA_GENERATE_STREAM
, std::string(),
124 MEDIA_DEVICE_AUDIO_CAPTURE
,
125 MEDIA_DEVICE_VIDEO_CAPTURE
));
126 MediaStreamRequest
* request_ptr
= request
.get();
127 proxy_
->RequestAccess(
128 request
.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
129 base::Unretained(&response_callback_
)));
130 MediaResponseCallback callback
;
131 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
),
133 .WillOnce(SaveArg
<1>(&callback
));
134 message_loop_
.RunUntilIdle();
135 ASSERT_FALSE(callback
.is_null());
137 MediaStreamDevices devices
;
139 MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE
, "Mic", "Mic"));
140 scoped_ptr
<MockMediaStreamUI
> ui(new MockMediaStreamUI());
141 EXPECT_CALL(*ui
, OnStarted(_
)).WillOnce(Return(0));
142 callback
.Run(devices
, MEDIA_DEVICE_OK
, ui
.Pass());
144 MediaStreamDevices response
;
145 EXPECT_CALL(response_callback_
, OnAccessRequestResponse(_
, _
))
146 .WillOnce(SaveArg
<0>(&response
));
147 message_loop_
.RunUntilIdle();
149 EXPECT_FALSE(response
.empty());
151 proxy_
->OnStarted(base::Closure(), MediaStreamUIProxy::WindowIdCallback());
152 message_loop_
.RunUntilIdle();
155 // Verify that the proxy can be deleted before the request is processed.
156 TEST_F(MediaStreamUIProxyTest
, DeleteBeforeAccepted
) {
157 scoped_ptr
<MediaStreamRequest
> request (
158 new MediaStreamRequest(0, 0, 0,
159 GURL("http://origin/"), false,
160 MEDIA_GENERATE_STREAM
, std::string(),
162 MEDIA_DEVICE_AUDIO_CAPTURE
,
163 MEDIA_DEVICE_VIDEO_CAPTURE
));
164 MediaStreamRequest
* request_ptr
= request
.get();
165 proxy_
->RequestAccess(
166 request
.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
167 base::Unretained(&response_callback_
)));
168 MediaResponseCallback callback
;
169 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
)
171 .WillOnce(SaveArg
<1>(&callback
));
172 message_loop_
.RunUntilIdle();
173 ASSERT_FALSE(callback
.is_null());
177 MediaStreamDevices devices
;
178 scoped_ptr
<MediaStreamUI
> ui
;
179 callback
.Run(devices
, MEDIA_DEVICE_OK
, ui
.Pass());
182 TEST_F(MediaStreamUIProxyTest
, StopFromUI
) {
183 scoped_ptr
<MediaStreamRequest
> request (
184 new MediaStreamRequest(0, 0, 0,
185 GURL("http://origin/"), false,
186 MEDIA_GENERATE_STREAM
, std::string(),
188 MEDIA_DEVICE_AUDIO_CAPTURE
,
189 MEDIA_DEVICE_VIDEO_CAPTURE
));
190 MediaStreamRequest
* request_ptr
= request
.get();
191 proxy_
->RequestAccess(
192 request
.Pass(), base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
193 base::Unretained(&response_callback_
)));
194 MediaResponseCallback callback
;
195 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
)
197 .WillOnce(SaveArg
<1>(&callback
));
198 message_loop_
.RunUntilIdle();
199 ASSERT_FALSE(callback
.is_null());
201 base::Closure stop_callback
;
203 MediaStreamDevices devices
;
205 MediaStreamDevice(MEDIA_DEVICE_AUDIO_CAPTURE
, "Mic", "Mic"));
206 scoped_ptr
<MockMediaStreamUI
> ui(new MockMediaStreamUI());
207 EXPECT_CALL(*ui
, OnStarted(_
))
208 .WillOnce(testing::DoAll(SaveArg
<0>(&stop_callback
), Return(0)));
209 callback
.Run(devices
, MEDIA_DEVICE_OK
, ui
.Pass());
211 MediaStreamDevices response
;
212 EXPECT_CALL(response_callback_
, OnAccessRequestResponse(_
, _
))
213 .WillOnce(SaveArg
<0>(&response
));
214 message_loop_
.RunUntilIdle();
216 EXPECT_FALSE(response
.empty());
218 MockStopStreamHandler stop_handler
;
219 proxy_
->OnStarted(base::Bind(&MockStopStreamHandler::OnStop
,
220 base::Unretained(&stop_handler
)),
221 MediaStreamUIProxy::WindowIdCallback());
222 message_loop_
.RunUntilIdle();
224 ASSERT_FALSE(stop_callback
.is_null());
225 EXPECT_CALL(stop_handler
, OnStop());
227 message_loop_
.RunUntilIdle();
230 TEST_F(MediaStreamUIProxyTest
, WindowIdCallbackCalled
) {
231 scoped_ptr
<MediaStreamRequest
> request (
232 new MediaStreamRequest(0, 0, 0,
233 GURL("http://origin/"), false,
234 MEDIA_GENERATE_STREAM
, std::string(),
237 MEDIA_DESKTOP_VIDEO_CAPTURE
));
238 MediaStreamRequest
* request_ptr
= request
.get();
240 proxy_
->RequestAccess(
242 base::Bind(&MockResponseCallback::OnAccessRequestResponse
,
243 base::Unretained(&response_callback_
)));
244 MediaResponseCallback callback
;
245 EXPECT_CALL(delegate_
, RequestMediaAccessPermission(SameRequest(request_ptr
),
247 .WillOnce(SaveArg
<1>(&callback
));
248 message_loop_
.RunUntilIdle();
250 const int kWindowId
= 1;
251 scoped_ptr
<MockMediaStreamUI
> ui(new MockMediaStreamUI());
252 EXPECT_CALL(*ui
, OnStarted(_
)).WillOnce(Return(kWindowId
));
254 callback
.Run(MediaStreamDevices(), MEDIA_DEVICE_OK
, ui
.Pass());
255 EXPECT_CALL(response_callback_
, OnAccessRequestResponse(_
, _
));
257 MockStopStreamHandler handler
;
258 EXPECT_CALL(handler
, OnWindowId(kWindowId
));
261 base::Bind(&MockStopStreamHandler::OnStop
, base::Unretained(&handler
)),
262 base::Bind(&MockStopStreamHandler::OnWindowId
,
263 base::Unretained(&handler
)));
264 message_loop_
.RunUntilIdle();
267 TEST_F(MediaStreamUIProxyTest
, CheckAccess
) {
268 proxy_
->CheckAccess(GURL("http://origin/"),
269 MEDIA_DEVICE_AUDIO_CAPTURE
,
272 base::Bind(&MockResponseCallback::OnCheckResponse
,
273 base::Unretained(&response_callback_
)));
274 EXPECT_CALL(delegate_
, CheckMediaAccessPermission(_
, _
));
275 EXPECT_CALL(response_callback_
, OnCheckResponse(_
));
276 message_loop_
.RunUntilIdle();