media_stream_manager.h revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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/scoped_ptr.h"
31#include "base/memory/ref_counted.h"
32#include "base/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/media/media_stream_options.h"
36#include "content/common/content_export.h"
37
38namespace base {
39class Thread;
40}
41
42namespace media {
43class AudioManager;
44}
45
46namespace content {
47
48class AudioInputDeviceManager;
49class FakeMediaStreamUIProxy;
50class MediaStreamDeviceSettings;
51class MediaStreamRequester;
52class MediaStreamUIProxy;
53class 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.
59class 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