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 "content/browser/renderer_host/render_view_host_delegate.h"
8 #include "content/browser/renderer_host/render_view_host_impl.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "media/video/capture/fake_video_capture_device.h"
14 class MediaStreamUIProxy::Core
{
16 explicit Core(const base::WeakPtr
<MediaStreamUIProxy
>& proxy
,
17 RenderViewHostDelegate
* test_render_delegate
);
20 void RequestAccess(const MediaStreamRequest
& request
);
24 void ProcessAccessRequestResponse(const MediaStreamDevices
& devices
,
25 scoped_ptr
<MediaStreamUI
> stream_ui
);
26 void ProcessStopRequestFromUI();
28 base::WeakPtr
<MediaStreamUIProxy
> proxy_
;
29 scoped_ptr
<MediaStreamUI
> ui_
;
31 RenderViewHostDelegate
* const test_render_delegate_
;
33 // WeakPtr<> is used to RequestMediaAccessPermission() because there is no way
34 // cancel media requests.
35 base::WeakPtrFactory
<Core
> weak_factory_
;
37 DISALLOW_COPY_AND_ASSIGN(Core
);
40 MediaStreamUIProxy::Core::Core(const base::WeakPtr
<MediaStreamUIProxy
>& proxy
,
41 RenderViewHostDelegate
* test_render_delegate
)
43 test_render_delegate_(test_render_delegate
),
47 MediaStreamUIProxy::Core::~Core() {
48 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
51 void MediaStreamUIProxy::Core::RequestAccess(
52 const MediaStreamRequest
& request
) {
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
55 RenderViewHostDelegate
* render_delegate
;
57 if (test_render_delegate_
) {
58 render_delegate
= test_render_delegate_
;
60 RenderViewHostImpl
* host
= RenderViewHostImpl::FromID(
61 request
.render_process_id
, request
.render_view_id
);
63 // Tab may have gone away.
64 if (!host
|| !host
->GetDelegate()) {
65 ProcessAccessRequestResponse(
66 MediaStreamDevices(), scoped_ptr
<MediaStreamUI
>());
70 render_delegate
= host
->GetDelegate();
73 render_delegate
->RequestMediaAccessPermission(
74 request
, base::Bind(&Core::ProcessAccessRequestResponse
,
75 weak_factory_
.GetWeakPtr()));
78 void MediaStreamUIProxy::Core::OnStarted() {
79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
81 ui_
->OnStarted(base::Bind(&Core::ProcessStopRequestFromUI
,
82 base::Unretained(this)));
86 void MediaStreamUIProxy::Core::ProcessAccessRequestResponse(
87 const MediaStreamDevices
& devices
,
88 scoped_ptr
<MediaStreamUI
> stream_ui
) {
89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
91 ui_
= stream_ui
.Pass();
92 BrowserThread::PostTask(
93 BrowserThread::IO
, FROM_HERE
,
94 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse
,
98 void MediaStreamUIProxy::Core::ProcessStopRequestFromUI() {
99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI
));
101 BrowserThread::PostTask(
102 BrowserThread::IO
, FROM_HERE
,
103 base::Bind(&MediaStreamUIProxy::ProcessStopRequestFromUI
, proxy_
));
107 scoped_ptr
<MediaStreamUIProxy
> MediaStreamUIProxy::Create() {
108 return scoped_ptr
<MediaStreamUIProxy
>(new MediaStreamUIProxy(NULL
));
112 scoped_ptr
<MediaStreamUIProxy
> MediaStreamUIProxy::CreateForTests(
113 RenderViewHostDelegate
* render_delegate
) {
114 return scoped_ptr
<MediaStreamUIProxy
>(
115 new MediaStreamUIProxy(render_delegate
));
118 MediaStreamUIProxy::MediaStreamUIProxy(
119 RenderViewHostDelegate
* test_render_delegate
)
120 : weak_factory_(this) {
121 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
122 core_
.reset(new Core(weak_factory_
.GetWeakPtr(), test_render_delegate
));
125 MediaStreamUIProxy::~MediaStreamUIProxy() {
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
127 BrowserThread::DeleteSoon(BrowserThread::UI
, FROM_HERE
, core_
.release());
130 void MediaStreamUIProxy::RequestAccess(
131 const MediaStreamRequest
& request
,
132 const ResponseCallback
& response_callback
) {
133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
135 response_callback_
= response_callback
;
136 BrowserThread::PostTask(
137 BrowserThread::UI
, FROM_HERE
,
138 base::Bind(&Core::RequestAccess
, base::Unretained(core_
.get()), request
));
141 void MediaStreamUIProxy::OnStarted(const base::Closure
& stop_callback
) {
142 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
144 stop_callback_
= stop_callback
;
145 BrowserThread::PostTask(
146 BrowserThread::UI
, FROM_HERE
,
147 base::Bind(&Core::OnStarted
, base::Unretained(core_
.get())));
150 void MediaStreamUIProxy::ProcessAccessRequestResponse(
151 const MediaStreamDevices
& devices
) {
152 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
153 DCHECK(!response_callback_
.is_null());
155 ResponseCallback cb
= response_callback_
;
156 response_callback_
.Reset();
160 void MediaStreamUIProxy::ProcessStopRequestFromUI() {
161 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
162 DCHECK(!stop_callback_
.is_null());
164 base::Closure cb
= stop_callback_
;
165 stop_callback_
.Reset();
169 FakeMediaStreamUIProxy::FakeMediaStreamUIProxy()
170 : MediaStreamUIProxy(NULL
) {
173 FakeMediaStreamUIProxy::~FakeMediaStreamUIProxy() {}
175 void FakeMediaStreamUIProxy::SetAvailableDevices(
176 const MediaStreamDevices
& devices
) {
180 void FakeMediaStreamUIProxy::RequestAccess(
181 const MediaStreamRequest
& request
,
182 const ResponseCallback
& response_callback
) {
183 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
185 response_callback_
= response_callback
;
187 MediaStreamDevices devices_to_use
;
188 bool accepted_audio
= false;
189 bool accepted_video
= false;
190 // Use the first capture device of the same media type in the list for the
192 for (MediaStreamDevices::const_iterator it
= devices_
.begin();
193 it
!= devices_
.end(); ++it
) {
194 if (!accepted_audio
&&
195 IsAudioMediaType(request
.audio_type
) &&
196 IsAudioMediaType(it
->type
)) {
197 devices_to_use
.push_back(*it
);
198 accepted_audio
= true;
199 } else if (!accepted_video
&&
200 IsVideoMediaType(request
.video_type
) &&
201 IsVideoMediaType(it
->type
)) {
202 devices_to_use
.push_back(*it
);
203 accepted_video
= true;
207 BrowserThread::PostTask(
208 BrowserThread::IO
, FROM_HERE
,
209 base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse
,
210 weak_factory_
.GetWeakPtr(), devices_to_use
));
213 void FakeMediaStreamUIProxy::OnStarted(const base::Closure
& stop_callback
) {
216 } // namespace content