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.
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
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.
20 // When enumeration and open are done in separate operations,
21 // MediaStreamUIController is not involved as in steps.
23 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_
24 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_
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 #include "content/public/browser/media_request_state.h"
49 class AudioInputDeviceManager
;
50 class FakeMediaStreamUIProxy
;
51 class MediaStreamDeviceSettings
;
52 class MediaStreamRequester
;
53 class MediaStreamUIProxy
;
54 class ResourceContext
;
55 class VideoCaptureManager
;
57 // MediaStreamManager is used to generate and close new media devices, not to
58 // start the media flow. The classes requesting new media streams are answered
59 // using MediaStreamRequester.
60 class CONTENT_EXPORT MediaStreamManager
61 : public MediaStreamProviderListener
,
62 public base::MessageLoop::DestructionObserver
,
63 public base::SystemMonitor::DevicesChangedObserver
{
65 // Callback to deliver the result of a media request.
66 typedef base::Callback
<void(const MediaStreamDevices
& devices
,
67 scoped_ptr
<MediaStreamUIProxy
> ui
)>
68 MediaRequestResponseCallback
;
70 explicit MediaStreamManager(media::AudioManager
* audio_manager
);
71 virtual ~MediaStreamManager();
73 // Used to access VideoCaptureManager.
74 VideoCaptureManager
* video_capture_manager();
76 // Used to access AudioInputDeviceManager.
77 AudioInputDeviceManager
* audio_input_device_manager();
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
,
89 const StreamOptions
& options
,
90 const GURL
& security_origin
,
91 const MediaRequestResponseCallback
& callback
);
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 void GenerateStream(MediaStreamRequester
* requester
,
98 int render_process_id
,
102 const StreamOptions
& components
,
103 const GURL
& security_origin
);
105 void CancelRequest(int render_process_id
,
107 int page_request_id
);
109 // Cancel an open request identified by |label|.
110 virtual void CancelRequest(const std::string
& label
);
112 // Cancel all requests for the given |render_process_id|.
113 void CancelAllRequests(int render_process_id
);
115 // Closes the stream device for a certain render view. The stream must have
116 // been opened by a call to GenerateStream.
117 void StopStreamDevice(int render_process_id
,
119 const std::string
& device_id
);
121 // Gets a list of devices of |type|, which must be MEDIA_DEVICE_AUDIO_CAPTURE
122 // or MEDIA_DEVICE_VIDEO_CAPTURE.
123 // The request is identified using the string returned to the caller.
124 // When the |requester| is NULL, MediaStreamManager will enumerate both audio
125 // and video devices and also start monitoring device changes, such as
126 // plug/unplug. The new device lists will be delivered via media observer to
127 // MediaCaptureDevicesDispatcher.
128 virtual std::string
EnumerateDevices(MediaStreamRequester
* requester
,
129 int render_process_id
,
133 MediaStreamType type
,
134 const GURL
& security_origin
);
136 // Open a device identified by |device_id|. |type| must be either
137 // MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
138 // The request is identified using string returned to the caller.
139 void OpenDevice(MediaStreamRequester
* requester
,
140 int render_process_id
,
144 const std::string
& device_id
,
145 MediaStreamType type
,
146 const GURL
& security_origin
);
148 // Called by UI to make sure the device monitor is started so that UI receive
149 // notifications about device changes.
150 void EnsureDeviceMonitorStarted();
152 // Implements MediaStreamProviderListener.
153 virtual void Opened(MediaStreamType stream_type
,
154 int capture_session_id
) OVERRIDE
;
155 virtual void Closed(MediaStreamType stream_type
,
156 int capture_session_id
) OVERRIDE
;
157 virtual void DevicesEnumerated(MediaStreamType stream_type
,
158 const StreamDeviceInfoArray
& devices
) OVERRIDE
;
160 // Implements base::SystemMonitor::DevicesChangedObserver.
161 virtual void OnDevicesChanged(
162 base::SystemMonitor::DeviceType device_type
) OVERRIDE
;
164 // Used by unit test to make sure fake devices are used instead of a real
165 // devices, which is needed for server based testing or certain tests (which
166 // can pass --use-fake-device-for-media-stream).
167 void UseFakeDevice();
169 // Called by the tests to specify a fake UI that should be used for next
170 // generated stream (or when using --use-fake-ui-for-media-stream).
171 void UseFakeUI(scoped_ptr
<FakeMediaStreamUIProxy
> fake_ui
);
173 // Returns all devices currently opened by a request with label |label|.
174 // If no request with |label| exist, an empty array is returned.
175 StreamDeviceInfoArray
GetDevicesOpenedByRequest(
176 const std::string
& label
) const;
178 // This object gets deleted on the UI thread after the IO thread has been
179 // destroyed. So we need to know when IO thread is being destroyed so that
180 // we can delete VideoCaptureManager and AudioInputDeviceManager. Normally
181 // this is handled by
182 // base::MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop.
183 // But for some tests which use TestBrowserThreadBundle, we need to call
184 // WillDestroyCurrentMessageLoop explicitly because the notification happens
185 // too late. (see http://crbug.com/247525#c14).
186 virtual void WillDestroyCurrentMessageLoop() OVERRIDE
;
190 MediaStreamManager();
193 // Contains all data needed to keep track of requests.
196 // Cache enumerated device list.
197 struct EnumerationCache
{
202 StreamDeviceInfoArray devices
;
205 typedef std::map
<std::string
, DeviceRequest
*> DeviceRequests
;
207 // Initializes the device managers on IO thread. Auto-starts the device
208 // thread and registers this as a listener with the device managers.
209 void InitializeDeviceManagersOnIOThread();
211 // Helper for sending up-to-date device lists to media observer when a
212 // capture device is plugged in or unplugged.
213 void NotifyDevicesChanged(MediaStreamType stream_type
,
214 const StreamDeviceInfoArray
& devices
);
216 void HandleAccessRequestResponse(const std::string
& label
,
217 const MediaStreamDevices
& devices
);
218 void StopMediaStreamFromBrowser(const std::string
& label
);
220 void DoEnumerateDevices(const std::string
& label
);
223 // Checks if all devices that was requested in the request identififed by
224 // |label| has been opened and set the request state accordingly.
225 void HandleRequestDone(const std::string
& label
,
226 DeviceRequest
* request
);
227 // Stop the use of the device associated with |session_id| of type |type| in
228 // all |requests_|. The device is removed from the request. If a request
229 /// doesn't use any devices as a consequence, the request is deleted.
230 void StopDevice(MediaStreamType type
, int session_id
);
231 // Calls the correct capture manager and close the device with |session_id|.
232 // All requests that uses the device are updated.
233 void CloseDevice(MediaStreamType type
, int session_id
);
234 // Returns true if a request for devices has been completed and the devices
235 // has either been opened or an error has occurred.
236 bool RequestDone(const DeviceRequest
& request
) const;
237 MediaStreamProvider
* GetDeviceManager(MediaStreamType stream_type
);
238 void StartEnumeration(DeviceRequest
* request
);
239 std::string
AddRequest(DeviceRequest
* request
);
240 DeviceRequest
* FindRequest(const std::string
& label
) const;
241 void DeleteRequest(const std::string
& label
);
242 void ClearEnumerationCache(EnumerationCache
* cache
);
243 // Returns true if the |cache| is invalid, false if it's invalid or if
244 // the |stream_type| is MEDIA_NO_SERVICE.
245 // On Android, this function will always return true for
246 // MEDIA_DEVICE_AUDIO_CAPTURE since we don't have a SystemMonitor to tell
247 // us about audio device changes.
248 bool EnumerationRequired(EnumerationCache
* cache
, MediaStreamType type
);
249 // Prepare the request with label |label| by starting device enumeration if
251 void SetupRequest(const std::string
& label
);
252 // Prepare |request| of type MEDIA_DEVICE_AUDIO_CAPTURE and/or
253 // MEDIA_DEVICE_VIDEO_CAPTURE for being posted to the UI by parsing
254 // StreamOptions::Constraints for requested device IDs.
255 bool SetupDeviceCaptureRequest(DeviceRequest
* request
);
256 // Prepare |request| of type MEDIA_TAB_AUDIO_CAPTURE and/or
257 // MEDIA_TAB_VIDEO_CAPTURE for being posted to the UI by parsing
258 // StreamOptions::Constraints for requested tab capture IDs.
259 bool SetupTabCaptureRequest(DeviceRequest
* request
);
260 // Prepare |request| of type MEDIA_LOOPBACK_AUDIO_CAPTURE and/or
261 // MEDIA_DESKTOP_VIDEO_CAPTURE for being posted to the UI by parsing
262 // StreamOptions::Constraints for the requested desktop ID.
263 bool SetupScreenCaptureRequest(DeviceRequest
* request
);
264 // Called when a request has been setup and devices have been enumerated if
266 void PostRequestToUI(const std::string
& label
, DeviceRequest
* request
);
267 // Returns true if a device with |device_id| has already been requested with
268 // a render procecss_id and render_view_id and type equal to the the values
269 // in |request|. If it has been requested, |device_info| contain information
271 bool FindExistingRequestedDeviceInfo(
272 const DeviceRequest
& new_request
,
273 const MediaStreamDevice
& new_device_info
,
274 StreamDeviceInfo
* existing_device_info
,
275 MediaRequestState
* existing_request_state
) const;
277 void FinalizeGenerateStream(const std::string
& label
,
278 DeviceRequest
* request
);
279 void FinalizeRequestFailed(const std::string
& label
,
280 DeviceRequest
* request
);
281 void FinalizeOpenDevice(const std::string
& label
,
282 DeviceRequest
* request
);
283 void FinalizeMediaAccessRequest(const std::string
& label
,
284 DeviceRequest
* request
,
285 const MediaStreamDevices
& devices
);
286 void FinalizeEnumerateDevices(const std::string
& label
,
287 DeviceRequest
* request
);
289 // This method is called when an audio or video device is plugged in or
290 // removed. It make sure all MediaStreams that use a removed device is
291 // stopped and that the render process is notified. |old_devices| is the list
292 // of previously available devices. |new_devices| is the new
293 // list of currently available devices.
294 void StopRemovedDevices(const StreamDeviceInfoArray
& old_devices
,
295 const StreamDeviceInfoArray
& new_devices
);
296 // Helper method used by StopRemovedDevices to stop the use of a certain
298 void StopRemovedDevice(const MediaStreamDevice
& device
);
300 // Helpers to start and stop monitoring devices.
301 void StartMonitoring();
302 void StopMonitoring();
304 // Finds the requested device id from constraints. The requested device type
305 // must be MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
306 bool GetRequestedDeviceCaptureId(const DeviceRequest
* request
,
307 MediaStreamType type
,
308 std::string
* device_id
) const;
310 void TranslateDeviceIdToSourceId(DeviceRequest
* request
,
311 MediaStreamDevice
* device
);
313 // Finds and returns the device id corresponding to the given
314 // |source_id|. Returns true if there was a raw device id that matched the
315 // given |source_id|, false if nothing matched it.
316 bool TranslateSourceIdToDeviceId(
317 MediaStreamType stream_type
,
319 const GURL
& security_origin
,
320 const std::string
& source_id
,
321 std::string
* device_id
) const;
323 // Device thread shared by VideoCaptureManager and AudioInputDeviceManager.
324 scoped_ptr
<base::Thread
> device_thread_
;
326 media::AudioManager
* const audio_manager_
; // not owned
327 scoped_refptr
<AudioInputDeviceManager
> audio_input_device_manager_
;
328 scoped_refptr
<VideoCaptureManager
> video_capture_manager_
;
330 // Indicator of device monitoring state.
331 bool monitoring_started_
;
333 // Stores most recently enumerated device lists. The cache is cleared when
334 // monitoring is stopped or there is no request for that type of device.
335 EnumerationCache audio_enumeration_cache_
;
336 EnumerationCache video_enumeration_cache_
;
338 // Keeps track of live enumeration commands sent to VideoCaptureManager or
339 // AudioInputDeviceManager, in order to only enumerate when necessary.
340 int active_enumeration_ref_count_
[NUM_MEDIA_TYPES
];
342 // All non-closed request.
343 DeviceRequests requests_
;
345 // Hold a pointer to the IO loop to check we delete the device thread and
346 // managers on the right thread.
347 base::MessageLoop
* io_loop_
;
350 scoped_ptr
<FakeMediaStreamUIProxy
> fake_ui_
;
352 DISALLOW_COPY_AND_ASSIGN(MediaStreamManager
);
355 } // namespace content
357 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_