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
& components
,
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 std::string
GenerateStream(MediaStreamRequester
* requester
,
98 int render_process_id
,
102 const StreamOptions
& components
,
103 const GURL
& security_origin
);
105 virtual void CancelRequest(const std::string
& label
);
106 void CancelAllRequests(int render_process_id
);
108 // Closes the stream device for a certain render view. The stream must have
109 // been opened by a call to GenerateStream.
110 void StopStreamDevice(int render_process_id
,
112 const std::string
& device_id
);
114 // Gets a list of devices of |type|, which must be MEDIA_DEVICE_AUDIO_CAPTURE
115 // or MEDIA_DEVICE_VIDEO_CAPTURE.
116 // The request is identified using the string returned to the caller.
117 // When the |requester| is NULL, MediaStreamManager will enumerate both audio
118 // and video devices and also start monitoring device changes, such as
119 // plug/unplug. The new device lists will be delivered via media observer to
120 // MediaCaptureDevicesDispatcher.
121 virtual std::string
EnumerateDevices(MediaStreamRequester
* requester
,
122 int render_process_id
,
126 MediaStreamType type
,
127 const GURL
& security_origin
);
129 // Open a device identified by |device_id|. |type| must be either
130 // MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
131 // The request is identified using string returned to the caller.
132 std::string
OpenDevice(MediaStreamRequester
* requester
,
133 int render_process_id
,
137 const std::string
& device_id
,
138 MediaStreamType type
,
139 const GURL
& security_origin
);
141 // Called by UI to make sure the device monitor is started so that UI receive
142 // notifications about device changes.
143 void EnsureDeviceMonitorStarted();
145 // Implements MediaStreamProviderListener.
146 virtual void Opened(MediaStreamType stream_type
,
147 int capture_session_id
) OVERRIDE
;
148 virtual void Closed(MediaStreamType stream_type
,
149 int capture_session_id
) OVERRIDE
;
150 virtual void DevicesEnumerated(MediaStreamType stream_type
,
151 const StreamDeviceInfoArray
& devices
) OVERRIDE
;
153 // Implements base::SystemMonitor::DevicesChangedObserver.
154 virtual void OnDevicesChanged(
155 base::SystemMonitor::DeviceType device_type
) OVERRIDE
;
157 // Used by unit test to make sure fake devices are used instead of a real
158 // devices, which is needed for server based testing or certain tests (which
159 // can pass --use-fake-device-for-media-stream).
160 void UseFakeDevice();
162 // Called by the tests to specify a fake UI that should be used for next
163 // generated stream (or when using --use-fake-ui-for-media-stream).
164 void UseFakeUI(scoped_ptr
<FakeMediaStreamUIProxy
> fake_ui
);
166 // Returns all devices currently opened by a request with label |label|.
167 // If no request with |label| exist, an empty array is returned.
168 StreamDeviceInfoArray
GetDevicesOpenedByRequest(
169 const std::string
& label
) const;
171 // This object gets deleted on the UI thread after the IO thread has been
172 // destroyed. So we need to know when IO thread is being destroyed so that
173 // we can delete VideoCaptureManager and AudioInputDeviceManager. Normally
174 // this is handled by
175 // base::MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop.
176 // But for some tests which use TestBrowserThreadBundle, we need to call
177 // WillDestroyCurrentMessageLoop explicitly because the notification happens
178 // too late. (see http://crbug.com/247525#c14).
179 virtual void WillDestroyCurrentMessageLoop() OVERRIDE
;
183 MediaStreamManager();
186 // Contains all data needed to keep track of requests.
189 // Cache enumerated device list.
190 struct EnumerationCache
{
195 StreamDeviceInfoArray devices
;
198 typedef std::map
<std::string
, DeviceRequest
*> DeviceRequests
;
200 // Initializes the device managers on IO thread. Auto-starts the device
201 // thread and registers this as a listener with the device managers.
202 void InitializeDeviceManagersOnIOThread();
204 // Helper for sending up-to-date device lists to media observer when a
205 // capture device is plugged in or unplugged.
206 void NotifyDevicesChanged(MediaStreamType stream_type
,
207 const StreamDeviceInfoArray
& devices
);
209 void HandleAccessRequestResponse(const std::string
& label
,
210 const MediaStreamDevices
& devices
);
211 void StopMediaStreamFromBrowser(const std::string
& label
);
213 void DoEnumerateDevices(const std::string
& label
);
216 // Checks if all devices that was requested in the request identififed by
217 // |label| has been opened and set the request state accordingly.
218 void HandleRequestDone(const std::string
& label
,
219 DeviceRequest
* request
);
220 // Stop the use of the device associated with |session_id| of type |type| in
221 // all |requests_|. The device is removed from the request. If a request
222 /// doesn't use any devices as a consequence, the request is deleted.
223 void StopDevice(MediaStreamType type
, int session_id
);
224 // Calls the correct capture manager and close the device with |session_id|.
225 // All requests that uses the device are updated.
226 void CloseDevice(MediaStreamType type
, int session_id
);
227 // Returns true if a request for devices has been completed and the devices
228 // has either been opened or an error has occurred.
229 bool RequestDone(const DeviceRequest
& request
) const;
230 MediaStreamProvider
* GetDeviceManager(MediaStreamType stream_type
);
231 void StartEnumeration(DeviceRequest
* request
);
232 std::string
AddRequest(DeviceRequest
* request
);
233 DeviceRequest
* FindRequest(const std::string
& label
) const;
234 void DeleteRequest(const std::string
& label
);
235 void ClearEnumerationCache(EnumerationCache
* cache
);
236 // Prepare the request with label |label| by starting device enumeration if
238 void SetupRequest(const std::string
& label
);
239 bool SetupTabCaptureRequest(DeviceRequest
* request
);
240 bool SetupScreenCaptureRequest(DeviceRequest
* request
);
241 // Called when a request has been setup and devices have been enumerated if
242 // needed. If a certain source id has been requested, the source id is
243 // translated to a real device id before the request is posted to UI.
244 void PostRequestToUI(const std::string
& label
, DeviceRequest
* request
);
245 // Returns true if a device with |device_id| has already been requested with
246 // a render procecss_id and render_view_id and type equal to the the values
247 // in |request|. If it has been requested, |device_info| contain information
249 bool FindExistingRequestedDeviceInfo(
250 const DeviceRequest
& new_request
,
251 const MediaStreamDevice
& new_device_info
,
252 StreamDeviceInfo
* existing_device_info
,
253 MediaRequestState
* existing_request_state
) const;
255 void FinalizeGenerateStream(const std::string
& label
,
256 DeviceRequest
* request
);
257 void FinalizeRequestFailed(const std::string
& label
,
258 DeviceRequest
* request
);
259 void FinalizeOpenDevice(const std::string
& label
,
260 DeviceRequest
* request
);
261 void FinalizeMediaAccessRequest(const std::string
& label
,
262 DeviceRequest
* request
,
263 const MediaStreamDevices
& devices
);
264 void FinalizeEnumerateDevices(const std::string
& label
,
265 DeviceRequest
* request
);
267 // This method is called when an audio or video device is plugged in or
268 // removed. It make sure all MediaStreams that use a removed device is
269 // stopped and that the render process is notified. |old_devices| is the list
270 // of previously available devices. |new_devices| is the new
271 // list of currently available devices.
272 void StopRemovedDevices(const StreamDeviceInfoArray
& old_devices
,
273 const StreamDeviceInfoArray
& new_devices
);
274 // Helper method used by StopRemovedDevices to stop the use of a certain
276 void StopRemovedDevice(const MediaStreamDevice
& device
);
278 // Helpers to start and stop monitoring devices.
279 void StartMonitoring();
280 void StopMonitoring();
282 bool TranslateRequestedSourceIdToDeviceId(DeviceRequest
* request
);
283 void TranslateDeviceIdToSourceId(DeviceRequest
* request
,
284 MediaStreamDevice
* device
);
286 // Finds and returns the device id corresponding to the given
287 // |source_id|. Returns true if there was a raw device id that matched the
288 // given |source_id|, false if nothing matched it.
289 bool TranslateSourceIdToDeviceId(
290 MediaStreamType stream_type
,
292 const GURL
& security_origin
,
293 const std::string
& source_id
,
294 std::string
* device_id
);
296 // Device thread shared by VideoCaptureManager and AudioInputDeviceManager.
297 scoped_ptr
<base::Thread
> device_thread_
;
299 media::AudioManager
* const audio_manager_
; // not owned
300 scoped_refptr
<AudioInputDeviceManager
> audio_input_device_manager_
;
301 scoped_refptr
<VideoCaptureManager
> video_capture_manager_
;
303 // Indicator of device monitoring state.
304 bool monitoring_started_
;
306 // Stores most recently enumerated device lists. The cache is cleared when
307 // monitoring is stopped or there is no request for that type of device.
308 EnumerationCache audio_enumeration_cache_
;
309 EnumerationCache video_enumeration_cache_
;
311 // Keeps track of live enumeration commands sent to VideoCaptureManager or
312 // AudioInputDeviceManager, in order to only enumerate when necessary.
313 int active_enumeration_ref_count_
[NUM_MEDIA_TYPES
];
315 // All non-closed request.
316 DeviceRequests requests_
;
318 // Hold a pointer to the IO loop to check we delete the device thread and
319 // managers on the right thread.
320 base::MessageLoop
* io_loop_
;
323 scoped_ptr
<FakeMediaStreamUIProxy
> fake_ui_
;
325 DISALLOW_COPY_AND_ASSIGN(MediaStreamManager
);
328 } // namespace content
330 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_