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 // MediaStreamManager is used to open/enumerate media capture devices (video 6 // supported now). Call flow: 7 // 1. GenerateStream is called when a render process wants to use a capture 8 // device. 9 // 2. MediaStreamManager will ask MediaStreamUIController for permission to 10 // use devices and for which device to use. 11 // 3. MediaStreamManager will request the corresponding media device manager(s) 12 // to enumerate available devices. The result will be given to 13 // MediaStreamUIController. 14 // 4. MediaStreamUIController will, by posting the request to UI, let the 15 // users to select which devices to use and send callback to 16 // MediaStreamManager with the result. 17 // 5. MediaStreamManager will call the proper media device manager to open the 18 // device and let the MediaStreamRequester know it has been done. 19 20 // When enumeration and open are done in separate operations, 21 // MediaStreamUIController is not involved as in steps. 22 23 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_ 24 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_ 25 26 #include <map> 27 #include <string> 28 29 #include "base/basictypes.h" 30 #include "base/memory/ref_counted.h" 31 #include "base/memory/scoped_ptr.h" 32 #include "base/message_loop/message_loop.h" 33 #include "base/system_monitor/system_monitor.h" 34 #include "content/browser/renderer_host/media/media_stream_provider.h" 35 #include "content/common/content_export.h" 36 #include "content/common/media/media_stream_options.h" 37 38 namespace base { 39 class Thread; 40 } 41 42 namespace media { 43 class AudioManager; 44 } 45 46 namespace content { 47 48 class AudioInputDeviceManager; 49 class FakeMediaStreamUIProxy; 50 class MediaStreamDeviceSettings; 51 class MediaStreamRequester; 52 class MediaStreamUIProxy; 53 class VideoCaptureManager; 54 55 // MediaStreamManager is used to generate and close new media devices, not to 56 // start the media flow. 57 // The classes requesting new media streams are answered using 58 // MediaStreamManager::Listener. 59 class CONTENT_EXPORT MediaStreamManager 60 : public MediaStreamProviderListener, 61 public base::MessageLoop::DestructionObserver, 62 public base::SystemMonitor::DevicesChangedObserver { 63 public: 64 // Callback to deliver the result of a media request. |label| is the string 65 // to identify the request, 66 typedef base::Callback<void(const MediaStreamDevices& devices, 67 scoped_ptr<MediaStreamUIProxy> ui)> 68 MediaRequestResponseCallback; 69 70 explicit MediaStreamManager(media::AudioManager* audio_manager); 71 virtual ~MediaStreamManager(); 72 73 // Used to access VideoCaptureManager. 74 VideoCaptureManager* video_capture_manager(); 75 76 // Used to access AudioInputDeviceManager. 77 AudioInputDeviceManager* audio_input_device_manager(); 78 79 // Creates a new media access request which is identified by a unique string 80 // that's returned to the caller. This will trigger the infobar and ask users 81 // for access to the device. |render_process_id| and |render_view_id| refer 82 // to the view where the infobar will appear to the user. |callback| is 83 // used to send the selected device to the clients. An empty list of device 84 // will be returned if the users deny the access. 85 std::string MakeMediaAccessRequest( 86 int render_process_id, 87 int render_view_id, 88 int page_request_id, 89 const StreamOptions& components, 90 const GURL& security_origin, 91 const MediaRequestResponseCallback& callback); 92 93 // GenerateStream opens new media devices according to |components|. It 94 // creates a new request which is identified by a unique string that's 95 // returned to the caller. |render_process_id| and |render_view_id| refer to 96 // the view where the infobar will appear to the user. 97 std::string GenerateStream(MediaStreamRequester* requester, 98 int render_process_id, 99 int render_view_id, 100 int page_request_id, 101 const StreamOptions& components, 102 const GURL& security_origin); 103 104 void CancelRequest(const std::string& label); 105 106 // Closes generated stream. 107 virtual void StopGeneratedStream(const std::string& label); 108 109 // Gets a list of devices of |type|, which must be MEDIA_DEVICE_AUDIO_CAPTURE 110 // or MEDIA_DEVICE_VIDEO_CAPTURE. 111 // The request is identified using the string returned to the caller. 112 // When the |requester| is NULL, MediaStreamManager will enumerate both audio 113 // and video devices and also start monitoring device changes, such as 114 // plug/unplug. The new device lists will be delivered via media observer to 115 // MediaCaptureDevicesDispatcher. 116 virtual std::string EnumerateDevices(MediaStreamRequester* requester, 117 int render_process_id, 118 int render_view_id, 119 int page_request_id, 120 MediaStreamType type, 121 const GURL& security_origin); 122 123 // Open a device identified by |device_id|. |type| must be either 124 // MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE. 125 // The request is identified using string returned to the caller. 126 std::string OpenDevice(MediaStreamRequester* requester, 127 int render_process_id, 128 int render_view_id, 129 int page_request_id, 130 const std::string& device_id, 131 MediaStreamType type, 132 const GURL& security_origin); 133 134 // Implements MediaStreamProviderListener. 135 virtual void Opened(MediaStreamType stream_type, 136 int capture_session_id) OVERRIDE; 137 virtual void Closed(MediaStreamType stream_type, 138 int capture_session_id) OVERRIDE; 139 virtual void DevicesEnumerated(MediaStreamType stream_type, 140 const StreamDeviceInfoArray& devices) OVERRIDE; 141 virtual void Error(MediaStreamType stream_type, 142 int capture_session_id, 143 MediaStreamProviderError error) OVERRIDE; 144 145 // Implements base::SystemMonitor::DevicesChangedObserver. 146 virtual void OnDevicesChanged( 147 base::SystemMonitor::DeviceType device_type) OVERRIDE; 148 149 // Used by unit test to make sure fake devices are used instead of a real 150 // devices, which is needed for server based testing or certain tests (which 151 // can pass --use-fake-device-for-media-stream). 152 void UseFakeDevice(); 153 154 // Called by the tests to specify a fake UI that should be used for next 155 // generated stream (or when using --use-fake-ui-for-media-stream). 156 void UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui); 157 158 // This object gets deleted on the UI thread after the IO thread has been 159 // destroyed. So we need to know when IO thread is being destroyed so that 160 // we can delete VideoCaptureManager and AudioInputDeviceManager. 161 // We also must call this function explicitly in tests which use 162 // TestBrowserThreadBundle, because the notification happens too late in that 163 // case (see http://crbug.com/247525#c14). 164 virtual void WillDestroyCurrentMessageLoop() OVERRIDE; 165 166 protected: 167 // Used for testing. 168 MediaStreamManager(); 169 170 private: 171 // Contains all data needed to keep track of requests. 172 class DeviceRequest; 173 174 // Cache enumerated device list. 175 struct EnumerationCache { 176 EnumerationCache(); 177 ~EnumerationCache(); 178 179 bool valid; 180 StreamDeviceInfoArray devices; 181 }; 182 183 typedef std::map<std::string, DeviceRequest*> DeviceRequests; 184 185 // Initializes the device managers on IO thread. Auto-starts the device 186 // thread and registers this as a listener with the device managers. 187 void InitializeDeviceManagersOnIOThread(); 188 189 // Helper for sending up-to-date device lists to media observer when a 190 // capture device is plugged in or unplugged. 191 void NotifyDevicesChanged(MediaStreamType stream_type, 192 const StreamDeviceInfoArray& devices); 193 194 195 void HandleAccessRequestResponse(const std::string& label, 196 const MediaStreamDevices& devices); 197 void StopStreamFromUI(const std::string& label); 198 199 // Helpers. 200 bool RequestDone(const DeviceRequest& request) const; 201 MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type); 202 void StartEnumeration(DeviceRequest* request); 203 std::string AddRequest(DeviceRequest* request); 204 void RemoveRequest(DeviceRequests::iterator it); 205 void ClearEnumerationCache(EnumerationCache* cache); 206 void PostRequestToUI(const std::string& label); 207 void HandleRequest(const std::string& label); 208 209 // Sends cached device list to a client corresponding to the request 210 // identified by |label|. 211 void SendCachedDeviceList(EnumerationCache* cache, const std::string& label); 212 213 // Stop the request of enumerating devices indentified by |label|. 214 void StopEnumerateDevices(const std::string& label); 215 216 // Helpers to start and stop monitoring devices. 217 void StartMonitoring(); 218 void StopMonitoring(); 219 220 // Finds and returns the raw device id corresponding to the given 221 // |device_guid|. Returns true if there was a raw device id that matched the 222 // given |device_guid|, false if nothing matched it. 223 bool TranslateGUIDToRawId( 224 MediaStreamType stream_type, 225 const GURL& security_origin, 226 const std::string& device_guid, 227 std::string* raw_device_id); 228 229 // Device thread shared by VideoCaptureManager and AudioInputDeviceManager. 230 scoped_ptr<base::Thread> device_thread_; 231 232 media::AudioManager* const audio_manager_; // not owned 233 scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_; 234 scoped_refptr<VideoCaptureManager> video_capture_manager_; 235 236 // Indicator of device monitoring state. 237 bool monitoring_started_; 238 239 // Stores most recently enumerated device lists. The cache is cleared when 240 // monitoring is stopped or there is no request for that type of device. 241 EnumerationCache audio_enumeration_cache_; 242 EnumerationCache video_enumeration_cache_; 243 244 // Keeps track of live enumeration commands sent to VideoCaptureManager or 245 // AudioInputDeviceManager, in order to only enumerate when necessary. 246 int active_enumeration_ref_count_[NUM_MEDIA_TYPES]; 247 248 // All non-closed request. 249 DeviceRequests requests_; 250 251 // Hold a pointer to the IO loop to check we delete the device thread and 252 // managers on the right thread. 253 base::MessageLoop* io_loop_; 254 255 bool screen_capture_active_; 256 257 bool use_fake_ui_; 258 scoped_ptr<FakeMediaStreamUIProxy> fake_ui_; 259 260 DISALLOW_COPY_AND_ASSIGN(MediaStreamManager); 261 }; 262 263 } // namespace content 264 265 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_ 266