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 VideoCaptureManager;
56 // MediaStreamManager is used to generate and close new media devices, not to
57 // start the media flow. The classes requesting new media streams are answered
58 // using MediaStreamRequester.
59 class CONTENT_EXPORT MediaStreamManager
60 : public MediaStreamProviderListener,
61 public base::MessageLoop::DestructionObserver,
62 public base::SystemMonitor::DevicesChangedObserver {
64 // Callback to deliver the result of a media request.
65 typedef base::Callback<void(const MediaStreamDevices& devices,
66 scoped_ptr<MediaStreamUIProxy> ui)>
67 MediaRequestResponseCallback;
69 explicit MediaStreamManager(media::AudioManager* audio_manager);
70 virtual ~MediaStreamManager();
72 // Used to access VideoCaptureManager.
73 VideoCaptureManager* video_capture_manager();
75 // Used to access AudioInputDeviceManager.
76 AudioInputDeviceManager* audio_input_device_manager();
78 // Creates a new media access request which is identified by a unique string
79 // that's returned to the caller. This will trigger the infobar and ask users
80 // for access to the device. |render_process_id| and |render_view_id| refer
81 // to the view where the infobar will appear to the user. |callback| is
82 // used to send the selected device to the clients. An empty list of device
83 // will be returned if the users deny the access.
84 std::string MakeMediaAccessRequest(
85 int render_process_id,
88 const StreamOptions& components,
89 const GURL& security_origin,
90 const MediaRequestResponseCallback& callback);
92 // GenerateStream opens new media devices according to |components|. It
93 // creates a new request which is identified by a unique string that's
94 // returned to the caller. |render_process_id| and |render_view_id| refer to
95 // the view where the infobar will appear to the user.
96 std::string GenerateStream(MediaStreamRequester* requester,
97 int render_process_id,
100 const StreamOptions& components,
101 const GURL& security_origin);
103 virtual void CancelRequest(const std::string& label);
104 void CancelAllRequests(int render_process_id);
106 // Closes the stream device for a certain render view. The stream must have
107 // been opened by a call to GenerateStream.
108 void StopStreamDevice(int render_process_id,
110 const std::string& device_id);
112 // Gets a list of devices of |type|, which must be MEDIA_DEVICE_AUDIO_CAPTURE
113 // or MEDIA_DEVICE_VIDEO_CAPTURE.
114 // The request is identified using the string returned to the caller.
115 // When the |requester| is NULL, MediaStreamManager will enumerate both audio
116 // and video devices and also start monitoring device changes, such as
117 // plug/unplug. The new device lists will be delivered via media observer to
118 // MediaCaptureDevicesDispatcher.
119 virtual std::string EnumerateDevices(MediaStreamRequester* requester,
120 int render_process_id,
123 MediaStreamType type,
124 const GURL& security_origin);
126 // Open a device identified by |device_id|. |type| must be either
127 // MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
128 // The request is identified using string returned to the caller.
129 std::string OpenDevice(MediaStreamRequester* requester,
130 int render_process_id,
133 const std::string& device_id,
134 MediaStreamType type,
135 const GURL& security_origin);
137 // Implements MediaStreamProviderListener.
138 virtual void Opened(MediaStreamType stream_type,
139 int capture_session_id) OVERRIDE;
140 virtual void Closed(MediaStreamType stream_type,
141 int capture_session_id) OVERRIDE;
142 virtual void DevicesEnumerated(MediaStreamType stream_type,
143 const StreamDeviceInfoArray& devices) OVERRIDE;
144 virtual void Error(MediaStreamType stream_type,
145 int capture_session_id,
146 MediaStreamProviderError error) OVERRIDE;
148 // Implements base::SystemMonitor::DevicesChangedObserver.
149 virtual void OnDevicesChanged(
150 base::SystemMonitor::DeviceType device_type) OVERRIDE;
152 // Used by unit test to make sure fake devices are used instead of a real
153 // devices, which is needed for server based testing or certain tests (which
154 // can pass --use-fake-device-for-media-stream).
155 void UseFakeDevice();
157 // Called by the tests to specify a fake UI that should be used for next
158 // generated stream (or when using --use-fake-ui-for-media-stream).
159 void UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui);
161 // This object gets deleted on the UI thread after the IO thread has been
162 // destroyed. So we need to know when IO thread is being destroyed so that
163 // we can delete VideoCaptureManager and AudioInputDeviceManager.
164 // We also must call this function explicitly in tests which use
165 // TestBrowserThreadBundle, because the notification happens too late in that
166 // case (see http://crbug.com/247525#c14).
167 virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
171 MediaStreamManager();
174 friend class MockMediaStreamDispatcherHost;
176 // Contains all data needed to keep track of requests.
179 // Cache enumerated device list.
180 struct EnumerationCache {
185 StreamDeviceInfoArray devices;
188 typedef std::map<std::string, DeviceRequest*> DeviceRequests;
190 // Initializes the device managers on IO thread. Auto-starts the device
191 // thread and registers this as a listener with the device managers.
192 void InitializeDeviceManagersOnIOThread();
194 // Helper for sending up-to-date device lists to media observer when a
195 // capture device is plugged in or unplugged.
196 void NotifyDevicesChanged(MediaStreamType stream_type,
197 const StreamDeviceInfoArray& devices);
200 void HandleAccessRequestResponse(const std::string& label,
201 const MediaStreamDevices& devices);
202 void StopMediaStreamFromBrowser(const std::string& label);
205 // Checks if all devices that was requested in the request identififed by
206 // |label| has been opened and set the request state accordingly.
207 void HandleRequestDone(const std::string& label,
208 DeviceRequest* request);
209 void StopDevice(const StreamDeviceInfo& device_info);
210 // Returns true if a request for devices has been completed and the devices
211 // has either been opened or an error has occurred.
212 bool RequestDone(const DeviceRequest& request) const;
213 MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type);
214 void StartEnumeration(DeviceRequest* request);
215 std::string AddRequest(DeviceRequest* request);
216 void RemoveRequest(DeviceRequests::iterator it);
217 void ClearEnumerationCache(EnumerationCache* cache);
218 void PostRequestToUI(const std::string& label);
219 void HandleRequest(const std::string& label);
220 // Returns true if a device with |device_id| has already been requested by
221 // |render_process_id| and |render_view_id| of type |type|. If it has been
222 // requested, |device_info| contain information about the the device.
223 bool FindExistingRequestedDeviceInfo(int render_process_id,
225 MediaStreamRequestType type,
226 const std::string& device_id,
227 StreamDeviceInfo* device_info,
228 MediaRequestState* request_state) const;
230 // Returns the label of the first request for a MediaStream that uses
232 std::string FindFirstMediaStreamRequestWithDevice(
233 const MediaStreamDevice& device) const;
235 // Sends cached device list to a client corresponding to the request
236 // identified by |label|.
237 void SendCachedDeviceList(EnumerationCache* cache, const std::string& label);
239 // This method is called when an audio or video device is plugged in or
240 // removed. It make sure all MediaStreams that use a removed device is
241 // stopped and that the render process is notified. |old_devices| is the list
242 // of previously available devices. |new_devices| is the new
243 // list of currently available devices.
244 void StopRemovedDevices(const StreamDeviceInfoArray& old_devices,
245 const StreamDeviceInfoArray& new_devices);
247 // Helpers to start and stop monitoring devices.
248 void StartMonitoring();
249 void StopMonitoring();
251 // Finds and returns the raw device id corresponding to the given
252 // |device_guid|. Returns true if there was a raw device id that matched the
253 // given |device_guid|, false if nothing matched it.
254 bool TranslateGUIDToRawId(
255 MediaStreamType stream_type,
256 const GURL& security_origin,
257 const std::string& device_guid,
258 std::string* raw_device_id);
260 // Device thread shared by VideoCaptureManager and AudioInputDeviceManager.
261 scoped_ptr<base::Thread> device_thread_;
263 media::AudioManager* const audio_manager_; // not owned
264 scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_;
265 scoped_refptr<VideoCaptureManager> video_capture_manager_;
267 // Indicator of device monitoring state.
268 bool monitoring_started_;
270 // Stores most recently enumerated device lists. The cache is cleared when
271 // monitoring is stopped or there is no request for that type of device.
272 EnumerationCache audio_enumeration_cache_;
273 EnumerationCache video_enumeration_cache_;
275 // Keeps track of live enumeration commands sent to VideoCaptureManager or
276 // AudioInputDeviceManager, in order to only enumerate when necessary.
277 int active_enumeration_ref_count_[NUM_MEDIA_TYPES];
279 // All non-closed request.
280 DeviceRequests requests_;
282 std::vector<int> opened_audio_session_ids_;
283 std::vector<int> opened_video_session_ids_;
285 // Hold a pointer to the IO loop to check we delete the device thread and
286 // managers on the right thread.
287 base::MessageLoop* io_loop_;
289 bool screen_capture_active_;
292 scoped_ptr<FakeMediaStreamUIProxy> fake_ui_;
294 DISALLOW_COPY_AND_ASSIGN(MediaStreamManager);
297 } // namespace content
299 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_