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. 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. 49 virtual void OnUpdateVideoDevices( 50 const content::MediaStreamDevices& devices) {} 51 52 // Handle an information update related to a media stream request. 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. 60 virtual void OnCreatingAudioStream(int render_process_id, 61 int render_view_id) {} 62 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