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