• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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.
4 
5 #ifndef CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
6 #define CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
7 
8 #include <deque>
9 #include <list>
10 #include <map>
11 
12 #include "base/callback.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/singleton.h"
15 #include "base/observer_list.h"
16 #include "content/public/browser/media_observer.h"
17 #include "content/public/browser/notification_observer.h"
18 #include "content/public/browser/notification_registrar.h"
19 #include "content/public/browser/web_contents_delegate.h"
20 #include "content/public/common/media_stream_request.h"
21 
22 class AudioStreamIndicator;
23 class DesktopStreamsRegistry;
24 class MediaStreamCaptureIndicator;
25 class Profile;
26 
27 namespace extensions {
28 class Extension;
29 }
30 
31 namespace user_prefs {
32 class PrefRegistrySyncable;
33 }
34 
35 // This singleton is used to receive updates about media events from the content
36 // layer.
37 class MediaCaptureDevicesDispatcher : public content::MediaObserver,
38                                       public content::NotificationObserver {
39  public:
40   class Observer {
41    public:
42     // Handle an information update consisting of a up-to-date audio capture
43     // device lists. This happens when a microphone is plugged in or unplugged.
OnUpdateAudioDevices(const content::MediaStreamDevices & devices)44     virtual void OnUpdateAudioDevices(
45         const content::MediaStreamDevices& devices) {}
46 
47     // Handle an information update consisting of a up-to-date video capture
48     // device lists. This happens when a camera is plugged in or unplugged.
OnUpdateVideoDevices(const content::MediaStreamDevices & devices)49     virtual void OnUpdateVideoDevices(
50         const content::MediaStreamDevices& devices) {}
51 
52     // Handle an information update related to a media stream request.
OnRequestUpdate(int render_process_id,int render_view_id,const content::MediaStreamDevice & device,const content::MediaRequestState state)53     virtual void OnRequestUpdate(
54         int render_process_id,
55         int render_view_id,
56         const content::MediaStreamDevice& device,
57         const content::MediaRequestState state) {}
58 
59     // Handle an information update that a new stream is being created.
OnCreatingAudioStream(int render_process_id,int render_view_id)60     virtual void OnCreatingAudioStream(int render_process_id,
61                                        int render_view_id) {}
62 
~Observer()63     virtual ~Observer() {}
64   };
65 
66   static MediaCaptureDevicesDispatcher* GetInstance();
67 
68   // Registers the preferences related to Media Stream default devices.
69   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
70 
71   // Methods for observers. Called on UI thread.
72   // Observers should add themselves on construction and remove themselves
73   // on destruction.
74   void AddObserver(Observer* observer);
75   void RemoveObserver(Observer* observer);
76   const content::MediaStreamDevices& GetAudioCaptureDevices();
77   const content::MediaStreamDevices& GetVideoCaptureDevices();
78 
79   // Method called from WebCapturerDelegate implementations to process access
80   // requests. |extension| is set to NULL if request was made from a drive-by
81   // page.
82   void ProcessMediaAccessRequest(
83       content::WebContents* web_contents,
84       const content::MediaStreamRequest& request,
85       const content::MediaResponseCallback& callback,
86       const extensions::Extension* extension);
87 
88   // Helper to get the default devices which can be used by the media request.
89   // Uses the first available devices if the default devices are not available.
90   // If the return list is empty, it means there is no available device on the
91   // OS.
92   // Called on the UI thread.
93   void GetDefaultDevicesForProfile(Profile* profile,
94                                    bool audio,
95                                    bool video,
96                                    content::MediaStreamDevices* devices);
97 
98   // Helpers for picking particular requested devices, identified by raw id.
99   // If the device requested is not available it will return NULL.
100   const content::MediaStreamDevice*
101   GetRequestedAudioDevice(const std::string& requested_audio_device_id);
102   const content::MediaStreamDevice*
103   GetRequestedVideoDevice(const std::string& requested_video_device_id);
104 
105   // Returns the first available audio or video device, or NULL if no devices
106   // are available.
107   const content::MediaStreamDevice* GetFirstAvailableAudioDevice();
108   const content::MediaStreamDevice* GetFirstAvailableVideoDevice();
109 
110   // Unittests that do not require actual device enumeration should call this
111   // API on the singleton. It is safe to call this multiple times on the
112   // signleton.
113   void DisableDeviceEnumerationForTesting();
114 
115   // Overridden from content::MediaObserver:
116   virtual void OnAudioCaptureDevicesChanged(
117       const content::MediaStreamDevices& devices) OVERRIDE;
118   virtual void OnVideoCaptureDevicesChanged(
119       const content::MediaStreamDevices& devices) OVERRIDE;
120   virtual void OnMediaRequestStateChanged(
121       int render_process_id,
122       int render_view_id,
123       int page_request_id,
124       const content::MediaStreamDevice& device,
125       content::MediaRequestState state) OVERRIDE;
126   virtual void OnAudioStreamPlayingChanged(
127       int render_process_id,
128       int render_view_id,
129       int stream_id,
130       bool is_playing,
131       float power_dBFS,
132       bool clipped) OVERRIDE;
133   virtual void OnCreatingAudioStream(int render_process_id,
134                                      int render_view_id) OVERRIDE;
135 
136   scoped_refptr<MediaStreamCaptureIndicator> GetMediaStreamCaptureIndicator();
137 
138   scoped_refptr<AudioStreamIndicator> GetAudioStreamIndicator();
139 
140   DesktopStreamsRegistry* GetDesktopStreamsRegistry();
141 
142   bool IsDesktopCaptureInProgress();
143 
144  private:
145   friend struct DefaultSingletonTraits<MediaCaptureDevicesDispatcher>;
146 
147   struct PendingAccessRequest {
148     PendingAccessRequest(const content::MediaStreamRequest& request,
149                          const content::MediaResponseCallback& callback);
150     ~PendingAccessRequest();
151 
152     content::MediaStreamRequest request;
153     content::MediaResponseCallback callback;
154   };
155   typedef std::deque<PendingAccessRequest> RequestsQueue;
156   typedef std::map<content::WebContents*, RequestsQueue> RequestsQueues;
157 
158   MediaCaptureDevicesDispatcher();
159   virtual ~MediaCaptureDevicesDispatcher();
160 
161   // content::NotificationObserver implementation.
162   virtual void Observe(int type,
163                        const content::NotificationSource& source,
164                        const content::NotificationDetails& details) OVERRIDE;
165 
166   // Helpers for ProcessMediaAccessRequest().
167   void ProcessDesktopCaptureAccessRequest(
168       content::WebContents* web_contents,
169       const content::MediaStreamRequest& request,
170       const content::MediaResponseCallback& callback,
171       const extensions::Extension* extension);
172   void ProcessScreenCaptureAccessRequest(
173       content::WebContents* web_contents,
174       const content::MediaStreamRequest& request,
175       const content::MediaResponseCallback& callback,
176       const extensions::Extension* extension);
177   void ProcessTabCaptureAccessRequest(
178       content::WebContents* web_contents,
179       const content::MediaStreamRequest& request,
180       const content::MediaResponseCallback& callback,
181       const extensions::Extension* extension);
182   void ProcessMediaAccessRequestFromPlatformAppOrExtension(
183       content::WebContents* web_contents,
184       const content::MediaStreamRequest& request,
185       const content::MediaResponseCallback& callback,
186       const extensions::Extension* extension);
187   void ProcessRegularMediaAccessRequest(
188       content::WebContents* web_contents,
189       const content::MediaStreamRequest& request,
190       const content::MediaResponseCallback& callback);
191   void ProcessQueuedAccessRequest(content::WebContents* web_contents);
192   void OnAccessRequestResponse(content::WebContents* web_contents,
193                                const content::MediaStreamDevices& devices,
194                                scoped_ptr<content::MediaStreamUI> ui);
195 
196   // Called by the MediaObserver() functions, executed on UI thread.
197   void UpdateAudioDevicesOnUIThread(const content::MediaStreamDevices& devices);
198   void UpdateVideoDevicesOnUIThread(const content::MediaStreamDevices& devices);
199   void UpdateMediaRequestStateOnUIThread(
200       int render_process_id,
201       int render_view_id,
202       int page_request_id,
203       const content::MediaStreamDevice& device,
204       content::MediaRequestState state);
205   void OnCreatingAudioStreamOnUIThread(int render_process_id,
206                                        int render_view_id);
207 
208   // A list of cached audio capture devices.
209   content::MediaStreamDevices audio_devices_;
210 
211   // A list of cached video capture devices.
212   content::MediaStreamDevices video_devices_;
213 
214   // A list of observers for the device update notifications.
215   ObserverList<Observer> observers_;
216 
217   // Flag to indicate if device enumeration has been done/doing.
218   // Only accessed on UI thread.
219   bool devices_enumerated_;
220 
221   // Flag used by unittests to disable device enumeration.
222   bool is_device_enumeration_disabled_;
223 
224   RequestsQueues pending_requests_;
225 
226   scoped_refptr<MediaStreamCaptureIndicator> media_stream_capture_indicator_;
227 
228   scoped_refptr<AudioStreamIndicator> audio_stream_indicator_;
229 
230   scoped_ptr<DesktopStreamsRegistry> desktop_streams_registry_;
231 
232   content::NotificationRegistrar notifications_registrar_;
233 
234   // Tracks MEDIA_DESKTOP_VIDEO_CAPTURE sessions which reach the
235   // MEDIA_REQUEST_STATE_DONE state.  Sessions are remove when
236   // MEDIA_REQUEST_STATE_CLOSING is encountered.
237   struct DesktopCaptureSession {
238     int render_process_id;
239     int render_view_id;
240     int page_request_id;
241   };
242   typedef std::list<DesktopCaptureSession> DesktopCaptureSessions;
243   DesktopCaptureSessions desktop_capture_sessions_;
244 
245   DISALLOW_COPY_AND_ASSIGN(MediaCaptureDevicesDispatcher);
246 };
247 
248 #endif  // CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
249