diff options
author | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-04 21:07:16 +0000 |
---|---|---|
committer | sergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-04 21:07:16 +0000 |
commit | 7fa1329a545a876382a9eaa0622f97fce881c0d4 (patch) | |
tree | cebdcfedda15aa1af6065aff18286e9880a52f24 /chrome/browser/media | |
parent | 41221d8548d758a2a9e6ec3c92d503a3de4f708d (diff) | |
download | chromium_src-7fa1329a545a876382a9eaa0622f97fce881c0d4.zip chromium_src-7fa1329a545a876382a9eaa0622f97fce881c0d4.tar.gz chromium_src-7fa1329a545a876382a9eaa0622f97fce881c0d4.tar.bz2 |
Replace MediaStreamUIController with MediaStreamUIProxy.
Previously a single object MediaStreamUIController was used to control UI for
all streams. Replaced it with a per-stream MediaStreamUIProxy that simplifies
code in many places.
Also moved media request queueing logic from content layer to chrome. Now
different types of requests may be queued differently (e.g. there is no
reason to block screen capture requests on webcam infobar).
This change was previously landed in 197222 and reverted in 197242
TBR=vrk@chromium.org
Review URL: https://codereview.chromium.org/16342002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204044 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/media')
3 files changed, 121 insertions, 8 deletions
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.cc b/chrome/browser/media/media_capture_devices_dispatcher.cc index 5fb643f..e33a652 100644 --- a/chrome/browser/media/media_capture_devices_dispatcher.cc +++ b/chrome/browser/media/media_capture_devices_dispatcher.cc @@ -25,6 +25,9 @@ #include "components/user_prefs/pref_registry_syncable.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/media_devices_monitor.h" +#include "content/public/browser/notification_service.h" +#include "content/public/browser/notification_source.h" +#include "content/public/browser/notification_types.h" #include "content/public/browser/web_contents.h" #include "content/public/common/media_stream_request.h" #include "extensions/common/constants.h" @@ -80,6 +83,15 @@ bool IsOriginWhitelistedForScreenCapture(const GURL& origin) { } // namespace +MediaCaptureDevicesDispatcher::PendingAccessRequest::PendingAccessRequest( + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) + : request(request), + callback(callback) { +} + +MediaCaptureDevicesDispatcher::PendingAccessRequest::~PendingAccessRequest() {} + MediaCaptureDevicesDispatcher* MediaCaptureDevicesDispatcher::GetInstance() { return Singleton<MediaCaptureDevicesDispatcher>::get(); } @@ -87,7 +99,11 @@ MediaCaptureDevicesDispatcher* MediaCaptureDevicesDispatcher::GetInstance() { MediaCaptureDevicesDispatcher::MediaCaptureDevicesDispatcher() : devices_enumerated_(false), media_stream_capture_indicator_(new MediaStreamCaptureIndicator()), - audio_stream_indicator_(new AudioStreamIndicator()) {} + audio_stream_indicator_(new AudioStreamIndicator()) { + notifications_registrar_.Add( + this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, + content::NotificationService::AllSources()); +} MediaCaptureDevicesDispatcher::~MediaCaptureDevicesDispatcher() {} @@ -138,6 +154,18 @@ MediaCaptureDevicesDispatcher::GetVideoCaptureDevices() { return video_devices_; } +void MediaCaptureDevicesDispatcher::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) { + content::WebContents* web_contents = + content::Source<content::WebContents>(source).ptr(); + pending_requests_.erase(web_contents); + } +} + void MediaCaptureDevicesDispatcher::ProcessMediaAccessRequest( content::WebContents* web_contents, const content::MediaStreamRequest& request, @@ -152,8 +180,7 @@ void MediaCaptureDevicesDispatcher::ProcessMediaAccessRequest( ProcessMediaAccessRequestFromExtension( web_contents, request, callback, extension); } else { - // For all regular media requests show infobar. - MediaStreamInfoBarDelegate::Create(web_contents, request, callback); + ProcessRegularMediaAccessRequest(web_contents, request, callback); } } @@ -259,6 +286,49 @@ void MediaCaptureDevicesDispatcher::ProcessMediaAccessRequestFromExtension( callback.Run(devices, ui.Pass()); } +void MediaCaptureDevicesDispatcher::ProcessRegularMediaAccessRequest( + content::WebContents* web_contents, + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + RequestsQueue& queue = pending_requests_[web_contents]; + queue.push(PendingAccessRequest(request, callback)); + + // If this is the only request then show the infobar. + if (queue.size() == 1) + ProcessQueuedAccessRequest(web_contents, queue.front()); +} + +void MediaCaptureDevicesDispatcher::ProcessQueuedAccessRequest( + content::WebContents* web_contents, + PendingAccessRequest& request) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + MediaStreamInfoBarDelegate::Create( + web_contents, request.request, + base::Bind(&MediaCaptureDevicesDispatcher::OnAccessRequestResponse, + base::Unretained(this), web_contents)); +} + +void MediaCaptureDevicesDispatcher::OnAccessRequestResponse( + content::WebContents* web_contents, + const content::MediaStreamDevices& devices, + scoped_ptr<content::MediaStreamUI> ui) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + std::map<content::WebContents*, RequestsQueue>::iterator it = + pending_requests_.find(web_contents); + DCHECK(it != pending_requests_.end()); + RequestsQueue& queue(it->second); + content::MediaResponseCallback callback = queue.front().callback; + queue.pop(); + if (!queue.empty()) + ProcessQueuedAccessRequest(web_contents, queue.front()); + + callback.Run(devices, ui.Pass()); +} + void MediaCaptureDevicesDispatcher::GetDefaultDevicesForProfile( Profile* profile, bool audio, diff --git a/chrome/browser/media/media_capture_devices_dispatcher.h b/chrome/browser/media/media_capture_devices_dispatcher.h index c9fb31c..7ff88da 100644 --- a/chrome/browser/media/media_capture_devices_dispatcher.h +++ b/chrome/browser/media/media_capture_devices_dispatcher.h @@ -5,11 +5,15 @@ #ifndef CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_ #define CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_ +#include <queue> + #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" #include "base/observer_list.h" #include "content/public/browser/media_observer.h" +#include "content/public/browser/notification_observer.h" +#include "content/public/browser/notification_registrar.h" #include "content/public/browser/web_contents_delegate.h" #include "content/public/common/media_stream_request.h" @@ -27,7 +31,8 @@ class PrefRegistrySyncable; // This singleton is used to receive updates about media events from the content // layer. -class MediaCaptureDevicesDispatcher : public content::MediaObserver { +class MediaCaptureDevicesDispatcher : public content::MediaObserver, + public content::NotificationObserver { public: class Observer { public: @@ -114,9 +119,24 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver { private: friend struct DefaultSingletonTraits<MediaCaptureDevicesDispatcher>; + struct PendingAccessRequest { + PendingAccessRequest(const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback); + ~PendingAccessRequest(); + + content::MediaStreamRequest request; + content::MediaResponseCallback callback; + }; + typedef std::queue<PendingAccessRequest> RequestsQueue; + MediaCaptureDevicesDispatcher(); virtual ~MediaCaptureDevicesDispatcher(); + // content::NotificationObserver implementation. + virtual void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) OVERRIDE; + // Helpers for ProcessMediaAccessRequest(). void ProcessScreenCaptureAccessRequest( content::WebContents* web_contents, @@ -127,6 +147,15 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver { const content::MediaStreamRequest& request, const content::MediaResponseCallback& callback, const extensions::Extension* extension); + void ProcessRegularMediaAccessRequest( + content::WebContents* web_contents, + const content::MediaStreamRequest& request, + const content::MediaResponseCallback& callback); + void ProcessQueuedAccessRequest(content::WebContents* web_contents, + PendingAccessRequest& request); + void OnAccessRequestResponse(content::WebContents* web_contents, + const content::MediaStreamDevices& devices, + scoped_ptr<content::MediaStreamUI> ui); // Called by the MediaObserver() functions, executed on UI thread. void UpdateAudioDevicesOnUIThread(const content::MediaStreamDevices& devices); @@ -150,9 +179,15 @@ class MediaCaptureDevicesDispatcher : public content::MediaObserver { // Only accessed on UI thread. bool devices_enumerated_; + std::map<content::WebContents*, RequestsQueue> pending_requests_; + scoped_refptr<MediaStreamCaptureIndicator> media_stream_capture_indicator_; scoped_refptr<AudioStreamIndicator> audio_stream_indicator_; + + content::NotificationRegistrar notifications_registrar_; + + DISALLOW_COPY_AND_ASSIGN(MediaCaptureDevicesDispatcher); }; #endif // CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_ diff --git a/chrome/browser/media/media_stream_devices_controller.cc b/chrome/browser/media/media_stream_devices_controller.cc index 9ea42f7..5bafcf8 100644 --- a/chrome/browser/media/media_stream_devices_controller.cc +++ b/chrome/browser/media/media_stream_devices_controller.cc @@ -83,7 +83,12 @@ MediaStreamDevicesController::MediaStreamDevicesController( } } -MediaStreamDevicesController::~MediaStreamDevicesController() {} +MediaStreamDevicesController::~MediaStreamDevicesController() { + if (!callback_.is_null()) { + callback_.Run(content::MediaStreamDevices(), + scoped_ptr<content::MediaStreamUI>()); + } +} // static void MediaStreamDevicesController::RegisterUserPrefs( @@ -195,7 +200,9 @@ void MediaStreamDevicesController::Accept(bool update_content_setting) { GetMediaStreamCaptureIndicator()->RegisterMediaStream( web_contents_, devices); } - callback_.Run(devices, ui.Pass()); + content::MediaResponseCallback cb = callback_; + callback_.Reset(); + cb.Run(devices, ui.Pass()); } void MediaStreamDevicesController::Deny(bool update_content_setting) { @@ -210,8 +217,9 @@ void MediaStreamDevicesController::Deny(bool update_content_setting) { if (update_content_setting) SetPermission(false); - callback_.Run(content::MediaStreamDevices(), - scoped_ptr<content::MediaStreamUI>()); + content::MediaResponseCallback cb = callback_; + callback_.Reset(); + cb.Run(content::MediaStreamDevices(), scoped_ptr<content::MediaStreamUI>()); } MediaStreamDevicesController::DevicePolicy |