- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / media / media_stream_ui_proxy.cc
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 "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"
11
12 namespace content {
13
14 class MediaStreamUIProxy::Core {
15  public:
16   explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
17                 RenderViewHostDelegate* test_render_delegate);
18   ~Core();
19
20   void RequestAccess(const MediaStreamRequest& request);
21   void OnStarted();
22
23  private:
24   void ProcessAccessRequestResponse(const MediaStreamDevices& devices,
25                                     scoped_ptr<MediaStreamUI> stream_ui);
26   void ProcessStopRequestFromUI();
27
28   base::WeakPtr<MediaStreamUIProxy> proxy_;
29   scoped_ptr<MediaStreamUI> ui_;
30
31   RenderViewHostDelegate* const test_render_delegate_;
32
33   // WeakPtr<> is used to RequestMediaAccessPermission() because there is no way
34   // cancel media requests.
35   base::WeakPtrFactory<Core> weak_factory_;
36
37   DISALLOW_COPY_AND_ASSIGN(Core);
38 };
39
40 MediaStreamUIProxy::Core::Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
41                                RenderViewHostDelegate* test_render_delegate)
42     : proxy_(proxy),
43       test_render_delegate_(test_render_delegate),
44       weak_factory_(this) {
45 }
46
47 MediaStreamUIProxy::Core::~Core() {
48   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
49 }
50
51 void MediaStreamUIProxy::Core::RequestAccess(
52     const MediaStreamRequest& request) {
53   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
54
55   RenderViewHostDelegate* render_delegate;
56
57   if (test_render_delegate_) {
58     render_delegate = test_render_delegate_;
59   } else {
60     RenderViewHostImpl* host = RenderViewHostImpl::FromID(
61         request.render_process_id, request.render_view_id);
62
63     // Tab may have gone away.
64     if (!host || !host->GetDelegate()) {
65       ProcessAccessRequestResponse(
66           MediaStreamDevices(), scoped_ptr<MediaStreamUI>());
67       return;
68     }
69
70     render_delegate = host->GetDelegate();
71   }
72
73   render_delegate->RequestMediaAccessPermission(
74       request, base::Bind(&Core::ProcessAccessRequestResponse,
75                           weak_factory_.GetWeakPtr()));
76 }
77
78 void MediaStreamUIProxy::Core::OnStarted() {
79   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
80   if (ui_) {
81     ui_->OnStarted(base::Bind(&Core::ProcessStopRequestFromUI,
82                               base::Unretained(this)));
83   }
84 }
85
86 void MediaStreamUIProxy::Core::ProcessAccessRequestResponse(
87     const MediaStreamDevices& devices,
88     scoped_ptr<MediaStreamUI> stream_ui) {
89   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
90
91   ui_ = stream_ui.Pass();
92   BrowserThread::PostTask(
93       BrowserThread::IO, FROM_HERE,
94       base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse,
95                  proxy_, devices));
96 }
97
98 void MediaStreamUIProxy::Core::ProcessStopRequestFromUI() {
99   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
100
101   BrowserThread::PostTask(
102       BrowserThread::IO, FROM_HERE,
103       base::Bind(&MediaStreamUIProxy::ProcessStopRequestFromUI, proxy_));
104 }
105
106 // static
107 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::Create() {
108   return scoped_ptr<MediaStreamUIProxy>(new MediaStreamUIProxy(NULL));
109 }
110
111 // static
112 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::CreateForTests(
113     RenderViewHostDelegate* render_delegate) {
114   return scoped_ptr<MediaStreamUIProxy>(
115       new MediaStreamUIProxy(render_delegate));
116 }
117
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));
123 }
124
125 MediaStreamUIProxy::~MediaStreamUIProxy() {
126   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
127   BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, core_.release());
128 }
129
130 void MediaStreamUIProxy::RequestAccess(
131     const MediaStreamRequest& request,
132     const ResponseCallback& response_callback) {
133   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
134
135   response_callback_ = response_callback;
136   BrowserThread::PostTask(
137       BrowserThread::UI, FROM_HERE,
138       base::Bind(&Core::RequestAccess, base::Unretained(core_.get()), request));
139 }
140
141 void MediaStreamUIProxy::OnStarted(const base::Closure& stop_callback) {
142   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
143
144   stop_callback_ = stop_callback;
145   BrowserThread::PostTask(
146       BrowserThread::UI, FROM_HERE,
147       base::Bind(&Core::OnStarted, base::Unretained(core_.get())));
148 }
149
150 void MediaStreamUIProxy::ProcessAccessRequestResponse(
151     const MediaStreamDevices& devices) {
152   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
153   DCHECK(!response_callback_.is_null());
154
155   ResponseCallback cb = response_callback_;
156   response_callback_.Reset();
157   cb.Run(devices);
158 }
159
160 void MediaStreamUIProxy::ProcessStopRequestFromUI() {
161   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
162   DCHECK(!stop_callback_.is_null());
163
164   base::Closure cb = stop_callback_;
165   stop_callback_.Reset();
166   cb.Run();
167 }
168
169 FakeMediaStreamUIProxy::FakeMediaStreamUIProxy()
170   : MediaStreamUIProxy(NULL) {
171 }
172
173 FakeMediaStreamUIProxy::~FakeMediaStreamUIProxy() {}
174
175 void FakeMediaStreamUIProxy::SetAvailableDevices(
176     const MediaStreamDevices& devices) {
177   devices_ = devices;
178 }
179
180 void FakeMediaStreamUIProxy::RequestAccess(
181     const MediaStreamRequest& request,
182     const ResponseCallback& response_callback) {
183   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
184
185   response_callback_ = response_callback;
186
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
191   // fake UI.
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;
204     }
205   }
206
207   BrowserThread::PostTask(
208       BrowserThread::IO, FROM_HERE,
209       base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse,
210                  weak_factory_.GetWeakPtr(), devices_to_use));
211 }
212
213 void FakeMediaStreamUIProxy::OnStarted(const base::Closure& stop_callback) {
214 }
215
216 }  // namespace content