Index: chrome/browser/media/media_capture_devices_dispatcher.cc |
diff --git a/chrome/browser/media/media_capture_devices_dispatcher.cc b/chrome/browser/media/media_capture_devices_dispatcher.cc |
index 7b0edd1618b52fef9ac8c27515c1a572ac97d12f..8c6f512d7a45a72ebc291e18c4b42f1ad305e2a4 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() {} |
@@ -136,6 +152,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, |
@@ -150,8 +178,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); |
} |
} |
@@ -252,6 +279,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, |