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 DesktopStreamsRegistry; 23 class MediaStreamCaptureIndicator; 24 class Profile; 25 26 namespace extensions { 27 class Extension; 28 } 29 30 namespace user_prefs { 31 class PrefRegistrySyncable; 32 } 33 34 // This singleton is used to receive updates about media events from the content 35 // layer. 36 class MediaCaptureDevicesDispatcher : public content::MediaObserver, 37 public content::NotificationObserver { 38 public: 39 class Observer { 40 public: 41 // Handle an information update consisting of a up-to-date audio capture 42 // device lists. This happens when a microphone is plugged in or unplugged. 43 virtual void OnUpdateAudioDevices( 44 const content::MediaStreamDevices& devices) {} 45 46 // Handle an information update consisting of a up-to-date video capture 47 // device lists. This happens when a camera is plugged in or unplugged. 48 virtual void OnUpdateVideoDevices( 49 const content::MediaStreamDevices& devices) {} 50 51 // Handle an information update related to a media stream request. 52 virtual void OnRequestUpdate( 53 int render_process_id, 54 int render_view_id, 55 const content::MediaStreamDevice& device, 56 const content::MediaRequestState state) {} 57 58 // Handle an information update that a new stream is being created. 59 virtual void OnCreatingAudioStream(int render_process_id, 60 int render_frame_id) {} 61 62 virtual ~Observer() {} 63 }; 64 65 static MediaCaptureDevicesDispatcher* GetInstance(); 66 67 // Registers the preferences related to Media Stream default devices. 68 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); 69 70 // Methods for observers. Called on UI thread. 71 // Observers should add themselves on construction and remove themselves 72 // on destruction. 73 void AddObserver(Observer* observer); 74 void RemoveObserver(Observer* observer); 75 const content::MediaStreamDevices& GetAudioCaptureDevices(); 76 const content::MediaStreamDevices& GetVideoCaptureDevices(); 77 78 // Method called from WebCapturerDelegate implementations to process access 79 // requests. |extension| is set to NULL if request was made from a drive-by 80 // page. 81 void ProcessMediaAccessRequest( 82 content::WebContents* web_contents, 83 const content::MediaStreamRequest& request, 84 const content::MediaResponseCallback& callback, 85 const extensions::Extension* extension); 86 87 // Helper to get the default devices which can be used by the media request. 88 // Uses the first available devices if the default devices are not available. 89 // If the return list is empty, it means there is no available device on the 90 // OS. 91 // Called on the UI thread. 92 void GetDefaultDevicesForProfile(Profile* profile, 93 bool audio, 94 bool video, 95 content::MediaStreamDevices* devices); 96 97 // Helpers for picking particular requested devices, identified by raw id. 98 // If the device requested is not available it will return NULL. 99 const content::MediaStreamDevice* 100 GetRequestedAudioDevice(const std::string& requested_audio_device_id); 101 const content::MediaStreamDevice* 102 GetRequestedVideoDevice(const std::string& requested_video_device_id); 103 104 // Returns the first available audio or video device, or NULL if no devices 105 // are available. 106 const content::MediaStreamDevice* GetFirstAvailableAudioDevice(); 107 const content::MediaStreamDevice* GetFirstAvailableVideoDevice(); 108 109 // Unittests that do not require actual device enumeration should call this 110 // API on the singleton. It is safe to call this multiple times on the 111 // signleton. 112 void DisableDeviceEnumerationForTesting(); 113 114 // Overridden from content::MediaObserver: 115 virtual void OnAudioCaptureDevicesChanged() OVERRIDE; 116 virtual void OnVideoCaptureDevicesChanged() OVERRIDE; 117 virtual void OnMediaRequestStateChanged( 118 int render_process_id, 119 int render_view_id, 120 int page_request_id, 121 const GURL& security_origin, 122 const content::MediaStreamDevice& device, 123 content::MediaRequestState state) OVERRIDE; 124 virtual void OnCreatingAudioStream(int render_process_id, 125 int render_frame_id) OVERRIDE; 126 virtual void OnAudioStreamPlaying( 127 int render_process_id, 128 int render_frame_id, 129 int stream_id, 130 const ReadPowerAndClipCallback& power_read_callback) OVERRIDE; 131 virtual void OnAudioStreamStopped( 132 int render_process_id, 133 int render_frame_id, 134 int stream_id) OVERRIDE; 135 136 scoped_refptr<MediaStreamCaptureIndicator> GetMediaStreamCaptureIndicator(); 137 138 DesktopStreamsRegistry* GetDesktopStreamsRegistry(); 139 140 bool IsDesktopCaptureInProgress(); 141 142 // Only for testing. 143 void SetTestAudioCaptureDevices(const content::MediaStreamDevices& devices); 144 void SetTestVideoCaptureDevices(const content::MediaStreamDevices& devices); 145 146 private: 147 friend struct DefaultSingletonTraits<MediaCaptureDevicesDispatcher>; 148 149 struct PendingAccessRequest { 150 PendingAccessRequest(const content::MediaStreamRequest& request, 151 const content::MediaResponseCallback& callback); 152 ~PendingAccessRequest(); 153 154 // TODO(gbillock): make the MediaStreamDevicesController owned by 155 // this object when we're using bubbles. 156 content::MediaStreamRequest request; 157 content::MediaResponseCallback callback; 158 }; 159 typedef std::deque<PendingAccessRequest> RequestsQueue; 160 typedef std::map<content::WebContents*, RequestsQueue> RequestsQueues; 161 162 MediaCaptureDevicesDispatcher(); 163 virtual ~MediaCaptureDevicesDispatcher(); 164 165 // content::NotificationObserver implementation. 166 virtual void Observe(int type, 167 const content::NotificationSource& source, 168 const content::NotificationDetails& details) OVERRIDE; 169 170 // Helpers for ProcessMediaAccessRequest(). 171 void ProcessDesktopCaptureAccessRequest( 172 content::WebContents* web_contents, 173 const content::MediaStreamRequest& request, 174 const content::MediaResponseCallback& callback, 175 const extensions::Extension* extension); 176 void ProcessScreenCaptureAccessRequest( 177 content::WebContents* web_contents, 178 const content::MediaStreamRequest& request, 179 const content::MediaResponseCallback& callback, 180 const extensions::Extension* extension); 181 void ProcessTabCaptureAccessRequest( 182 content::WebContents* web_contents, 183 const content::MediaStreamRequest& request, 184 const content::MediaResponseCallback& callback, 185 const extensions::Extension* extension); 186 void ProcessMediaAccessRequestFromPlatformAppOrExtension( 187 content::WebContents* web_contents, 188 const content::MediaStreamRequest& request, 189 const content::MediaResponseCallback& callback, 190 const extensions::Extension* extension); 191 void ProcessRegularMediaAccessRequest( 192 content::WebContents* web_contents, 193 const content::MediaStreamRequest& request, 194 const content::MediaResponseCallback& callback); 195 void ProcessQueuedAccessRequest(content::WebContents* web_contents); 196 void OnAccessRequestResponse(content::WebContents* web_contents, 197 const content::MediaStreamDevices& devices, 198 content::MediaStreamRequestResult result, 199 scoped_ptr<content::MediaStreamUI> ui); 200 201 // Called by the MediaObserver() functions, executed on UI thread. 202 void NotifyAudioDevicesChangedOnUIThread(); 203 void NotifyVideoDevicesChangedOnUIThread(); 204 void UpdateMediaRequestStateOnUIThread( 205 int render_process_id, 206 int render_view_id, 207 int page_request_id, 208 const GURL& security_origin, 209 const content::MediaStreamDevice& device, 210 content::MediaRequestState state); 211 void OnCreatingAudioStreamOnUIThread(int render_process_id, 212 int render_frame_id); 213 214 // Only for testing, a list of cached audio capture devices. 215 content::MediaStreamDevices test_audio_devices_; 216 217 // Only for testing, a list of cached video capture devices. 218 content::MediaStreamDevices test_video_devices_; 219 220 // A list of observers for the device update notifications. 221 ObserverList<Observer> observers_; 222 223 // Flag used by unittests to disable device enumeration. 224 bool is_device_enumeration_disabled_; 225 226 RequestsQueues pending_requests_; 227 228 scoped_refptr<MediaStreamCaptureIndicator> media_stream_capture_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