summaryrefslogtreecommitdiffstats
path: root/chrome/browser/media
diff options
context:
space:
mode:
authorsergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-04 21:07:16 +0000
committersergeyu@chromium.org <sergeyu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-04 21:07:16 +0000
commit7fa1329a545a876382a9eaa0622f97fce881c0d4 (patch)
treecebdcfedda15aa1af6065aff18286e9880a52f24 /chrome/browser/media
parent41221d8548d758a2a9e6ec3c92d503a3de4f708d (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/media/media_capture_devices_dispatcher.cc76
-rw-r--r--chrome/browser/media/media_capture_devices_dispatcher.h37
-rw-r--r--chrome/browser/media/media_stream_devices_controller.cc16
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