- add sources.
[platform/framework/web/crosswalk.git] / src / content / browser / renderer_host / media / media_stream_manager.h
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 #include "content/public/browser/media_request_state.h"
38
39 namespace base {
40 class Thread;
41 }
42
43 namespace media {
44 class AudioManager;
45 }
46
47 namespace content {
48
49 class AudioInputDeviceManager;
50 class FakeMediaStreamUIProxy;
51 class MediaStreamDeviceSettings;
52 class MediaStreamRequester;
53 class MediaStreamUIProxy;
54 class VideoCaptureManager;
55
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 {
63  public:
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;
68
69   explicit MediaStreamManager(media::AudioManager* audio_manager);
70   virtual ~MediaStreamManager();
71
72   // Used to access VideoCaptureManager.
73   VideoCaptureManager* video_capture_manager();
74
75   // Used to access AudioInputDeviceManager.
76   AudioInputDeviceManager* audio_input_device_manager();
77
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,
86       int render_view_id,
87       int page_request_id,
88       const StreamOptions& components,
89       const GURL& security_origin,
90       const MediaRequestResponseCallback& callback);
91
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,
98                              int render_view_id,
99                              int page_request_id,
100                              const StreamOptions& components,
101                              const GURL& security_origin);
102
103   virtual void CancelRequest(const std::string& label);
104   void CancelAllRequests(int render_process_id);
105
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,
109                         int render_view_id,
110                         const std::string& device_id);
111
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,
121                                        int render_view_id,
122                                        int page_request_id,
123                                        MediaStreamType type,
124                                        const GURL& security_origin);
125
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,
131                          int render_view_id,
132                          int page_request_id,
133                          const std::string& device_id,
134                          MediaStreamType type,
135                          const GURL& security_origin);
136
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;
147
148   // Implements base::SystemMonitor::DevicesChangedObserver.
149   virtual void OnDevicesChanged(
150       base::SystemMonitor::DeviceType device_type) OVERRIDE;
151
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();
156
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);
160
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;
168
169  protected:
170   // Used for testing.
171   MediaStreamManager();
172
173  private:
174   friend class MockMediaStreamDispatcherHost;
175
176   // Contains all data needed to keep track of requests.
177   class DeviceRequest;
178
179   // Cache enumerated device list.
180   struct EnumerationCache {
181     EnumerationCache();
182     ~EnumerationCache();
183
184     bool valid;
185     StreamDeviceInfoArray devices;
186   };
187
188   typedef std::map<std::string, DeviceRequest*> DeviceRequests;
189
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();
193
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);
198
199
200   void HandleAccessRequestResponse(const std::string& label,
201                                    const MediaStreamDevices& devices);
202   void StopMediaStreamFromBrowser(const std::string& label);
203
204   // Helpers.
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,
224                                        int render_view_id,
225                                        MediaStreamRequestType type,
226                                        const std::string& device_id,
227                                        StreamDeviceInfo* device_info,
228                                        MediaRequestState* request_state) const;
229
230   // Returns the label of the first request for a MediaStream that uses
231   // |device|.
232   std::string FindFirstMediaStreamRequestWithDevice(
233       const MediaStreamDevice& device) const;
234
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);
238
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);
246
247   // Helpers to start and stop monitoring devices.
248   void StartMonitoring();
249   void StopMonitoring();
250
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);
259
260   // Device thread shared by VideoCaptureManager and AudioInputDeviceManager.
261   scoped_ptr<base::Thread> device_thread_;
262
263   media::AudioManager* const audio_manager_;  // not owned
264   scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_;
265   scoped_refptr<VideoCaptureManager> video_capture_manager_;
266
267   // Indicator of device monitoring state.
268   bool monitoring_started_;
269
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_;
274
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];
278
279   // All non-closed request.
280   DeviceRequests requests_;
281
282   std::vector<int> opened_audio_session_ids_;
283   std::vector<int> opened_video_session_ids_;
284
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_;
288
289   bool screen_capture_active_;
290
291   bool use_fake_ui_;
292   scoped_ptr<FakeMediaStreamUIProxy> fake_ui_;
293
294   DISALLOW_COPY_AND_ASSIGN(MediaStreamManager);
295 };
296
297 }  // namespace content
298
299 #endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_