Index: content/browser/renderer_host/media/media_stream_ui_proxy.cc |
diff --git a/content/browser/renderer_host/media/media_stream_ui_proxy.cc b/content/browser/renderer_host/media/media_stream_ui_proxy.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f090522926beb91a264f842ad8562368ef7bf6ca |
--- /dev/null |
+++ b/content/browser/renderer_host/media/media_stream_ui_proxy.cc |
@@ -0,0 +1,207 @@ |
+// Copyright 2013 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "content/browser/renderer_host/media/media_stream_ui_proxy.h" |
+ |
+#include "content/browser/renderer_host/render_view_host_delegate.h" |
+#include "content/browser/renderer_host/render_view_host_impl.h" |
+#include "content/public/browser/browser_thread.h" |
+#include "media/video/capture/fake_video_capture_device.h" |
+ |
+namespace content { |
+ |
+class MediaStreamUIProxy::Core { |
+ public: |
+ explicit Core(const base::WeakPtr<MediaStreamUIProxy>& proxy); |
+ ~Core(); |
+ |
+ void RequestAccess(const MediaStreamRequest& request); |
+ void OnStarted(); |
+ |
+ void SetRenderViewHostDelegateForTests(RenderViewHostDelegate* delegate); |
+ |
+ private: |
+ void ProcessAccessRequestResponse(const MediaStreamDevices& devices, |
+ scoped_ptr<MediaStreamUI> stream_ui); |
+ void ProcessStopRequestFromUI(); |
+ |
+ base::WeakPtr<MediaStreamUIProxy> proxy_; |
+ scoped_ptr<MediaStreamUI> ui_; |
+ |
+ RenderViewHostDelegate* render_delegate_; |
+ |
+ // WeakPtr<> is used to RequestMediaAccessPermission() because there is no way |
+ // cancel media requests. |
+ base::WeakPtrFactory<Core> weak_factory_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(Core); |
+}; |
+ |
+MediaStreamUIProxy::Core::Core(const base::WeakPtr<MediaStreamUIProxy>& proxy) |
+ : proxy_(proxy), |
+ render_delegate_(NULL), |
+ weak_factory_(this) { |
+} |
+ |
+MediaStreamUIProxy::Core::~Core() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+} |
+ |
+void MediaStreamUIProxy::Core::RequestAccess( |
+ const MediaStreamRequest& request) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ if (!render_delegate_) { |
+ RenderViewHostImpl* host = RenderViewHostImpl::FromID( |
+ request.render_process_id, request.render_view_id); |
+ |
+ // Tab may have gone away. |
+ if (!host || !host->GetDelegate()) { |
+ ProcessAccessRequestResponse( |
+ MediaStreamDevices(), scoped_ptr<MediaStreamUI>()); |
+ return; |
+ } |
+ |
+ render_delegate_ = host->GetDelegate(); |
miu
2013/06/06 20:03:01
In this "set once lazily" scheme, will render_dele
Sergey Ulanov
2013/06/06 21:40:03
This method should only be called only once per in
|
+ } |
+ |
+ render_delegate_->RequestMediaAccessPermission( |
+ request, base::Bind(&Core::ProcessAccessRequestResponse, |
+ weak_factory_.GetWeakPtr())); |
+} |
+ |
+void MediaStreamUIProxy::Core::OnStarted() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ if (ui_) { |
+ ui_->OnStarted(base::Bind(&Core::ProcessStopRequestFromUI, |
+ base::Unretained(this))); |
+ } |
+} |
+ |
+void MediaStreamUIProxy::Core::SetRenderViewHostDelegateForTests( |
+ RenderViewHostDelegate* delegate) { |
+ render_delegate_ = delegate; |
+} |
+ |
+void MediaStreamUIProxy::Core::ProcessAccessRequestResponse( |
+ const MediaStreamDevices& devices, |
+ scoped_ptr<MediaStreamUI> stream_ui) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ ui_ = stream_ui.Pass(); |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse, |
+ proxy_, devices)); |
+} |
+ |
+void MediaStreamUIProxy::Core::ProcessStopRequestFromUI() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&MediaStreamUIProxy::ProcessStopRequestFromUI, proxy_)); |
+} |
+ |
+MediaStreamUIProxy::MediaStreamUIProxy() |
+ : weak_factory_(this) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ core_.reset(new Core(weak_factory_.GetWeakPtr())); |
+} |
+ |
+MediaStreamUIProxy::~MediaStreamUIProxy() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ BrowserThread::DeleteSoon(BrowserThread::UI, FROM_HERE, core_.release()); |
+} |
+ |
+void MediaStreamUIProxy::SetRenderViewHostDelegateForTests( |
miu
2013/06/06 20:03:01
Consider using injection (i.e., argument to the co
Sergey Ulanov
2013/06/06 21:40:03
Done.
|
+ RenderViewHostDelegate* delegate) { |
+ core_->SetRenderViewHostDelegateForTests(delegate); |
+} |
+ |
+void MediaStreamUIProxy::RequestAccess( |
+ const MediaStreamRequest& request, |
+ const ResponseCallback& response_callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ response_callback_ = response_callback; |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&Core::RequestAccess, base::Unretained(core_.get()), request)); |
+} |
+ |
+void MediaStreamUIProxy::OnStarted(const base::Closure& stop_callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ stop_callback_ = stop_callback; |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, FROM_HERE, |
+ base::Bind(&Core::OnStarted, base::Unretained(core_.get()))); |
+} |
+ |
+void MediaStreamUIProxy::ProcessAccessRequestResponse( |
+ const MediaStreamDevices& devices) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(!response_callback_.is_null()); |
+ |
+ ResponseCallback cb = response_callback_; |
+ response_callback_.Reset(); |
+ cb.Run(devices); |
+} |
+ |
+void MediaStreamUIProxy::ProcessStopRequestFromUI() { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ DCHECK(!stop_callback_.is_null()); |
+ |
+ base::Closure cb = stop_callback_; |
+ stop_callback_.Reset(); |
+ cb.Run(); |
+} |
+ |
+FakeMediaStreamUIProxy::FakeMediaStreamUIProxy() {} |
+ |
+FakeMediaStreamUIProxy::~FakeMediaStreamUIProxy() {} |
+ |
+void FakeMediaStreamUIProxy::SetAvailableDevices( |
+ const MediaStreamDevices& devices) { |
+ devices_ = devices; |
+} |
+ |
+void FakeMediaStreamUIProxy::RequestAccess( |
+ const MediaStreamRequest& request, |
+ const ResponseCallback& response_callback) { |
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
+ |
+ response_callback_ = response_callback; |
+ |
+ MediaStreamDevices devices_to_use; |
+ bool accepted_audio = false; |
+ bool accepted_video = false; |
+ // Use the first capture device of the same media type in the list for the |
+ // fake UI. |
+ for (MediaStreamDevices::const_iterator it = devices_.begin(); |
+ it != devices_.end(); ++it) { |
+ if (!accepted_audio && |
+ IsAudioMediaType(request.audio_type) && |
+ IsAudioMediaType(it->type)) { |
+ devices_to_use.push_back(*it); |
+ accepted_audio = true; |
+ } else if (!accepted_video && |
+ IsVideoMediaType(request.video_type) && |
+ IsVideoMediaType(it->type)) { |
+ devices_to_use.push_back(*it); |
+ accepted_video = true; |
+ } |
+ } |
+ |
+ BrowserThread::PostTask( |
+ BrowserThread::IO, FROM_HERE, |
+ base::Bind(&MediaStreamUIProxy::ProcessAccessRequestResponse, |
+ weak_factory_.GetWeakPtr(), devices_to_use)); |
+} |
+ |
+void FakeMediaStreamUIProxy::OnStarted(const base::Closure& stop_callback) { |
+} |
+ |
+} // namespace content |