Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / renderer_host / media / media_stream_ui_proxy.cc
blob3e4edbc0ac03b672d71c4aa2c91e06a997199cd6
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"
12 namespace content {
14 class MediaStreamUIProxy::Core {
15 public:
16 explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy,
17 RenderViewHostDelegate* test_render_delegate);
18 ~Core();
20 void RequestAccess(const MediaStreamRequest& request);
21 void OnStarted();
23 private:
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)
42 : proxy_(proxy),
43 test_render_delegate_(test_render_delegate),
44 weak_factory_(this) {
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_;
59 } else {
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>());
67 return;
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));
80 if (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,
95 proxy_, devices));
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_));
106 // static
107 scoped_ptr<MediaStreamUIProxy> MediaStreamUIProxy::Create() {
108 return scoped_ptr<MediaStreamUIProxy>(new MediaStreamUIProxy(NULL));
111 // static
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();
157 cb.Run(devices);
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();
166 cb.Run();
169 FakeMediaStreamUIProxy::FakeMediaStreamUIProxy()
170 : MediaStreamUIProxy(NULL) {
173 FakeMediaStreamUIProxy::~FakeMediaStreamUIProxy() {}
175 void FakeMediaStreamUIProxy::SetAvailableDevices(
176 const MediaStreamDevices& devices) {
177 devices_ = 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
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;
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