Upstream version 6.35.121.0
[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 <set>
28 #include <string>
29
30 #include "base/basictypes.h"
31 #include "base/memory/ref_counted.h"
32 #include "base/memory/scoped_ptr.h"
33 #include "base/message_loop/message_loop.h"
34 #include "base/system_monitor/system_monitor.h"
35 #include "content/browser/renderer_host/media/media_stream_provider.h"
36 #include "content/common/content_export.h"
37 #include "content/common/media/media_stream_options.h"
38 #include "content/public/browser/media_request_state.h"
39 #include "content/public/browser/resource_context.h"
40
41 namespace media {
42 class AudioManager;
43 }
44
45 namespace content {
46
47 class AudioInputDeviceManager;
48 class FakeMediaStreamUIProxy;
49 class MediaStreamDeviceSettings;
50 class MediaStreamRequester;
51 class MediaStreamUIProxy;
52 class VideoCaptureManager;
53
54 // MediaStreamManager is used to generate and close new media devices, not to
55 // start the media flow. The classes requesting new media streams are answered
56 // using MediaStreamRequester.
57 class CONTENT_EXPORT MediaStreamManager
58     : public MediaStreamProviderListener,
59       public base::MessageLoop::DestructionObserver,
60       public base::SystemMonitor::DevicesChangedObserver {
61  public:
62   // Callback to deliver the result of a media request.
63   typedef base::Callback<void(const MediaStreamDevices& devices,
64                               scoped_ptr<MediaStreamUIProxy> ui)>
65       MediaRequestResponseCallback;
66
67   explicit MediaStreamManager(media::AudioManager* audio_manager);
68   virtual ~MediaStreamManager();
69
70   // Used to access VideoCaptureManager.
71   VideoCaptureManager* video_capture_manager();
72
73   // Used to access AudioInputDeviceManager.
74   AudioInputDeviceManager* audio_input_device_manager();
75
76   // Creates a new media access request which is identified by a unique string
77   // that's returned to the caller. This will trigger the infobar and ask users
78   // for access to the device. |render_process_id| and |render_view_id| refer
79   // to the view where the infobar will appear to the user. |callback| is
80   // used to send the selected device to the clients. An empty list of device
81   // will be returned if the users deny the access.
82   std::string MakeMediaAccessRequest(
83       int render_process_id,
84       int render_view_id,
85       int page_request_id,
86       const StreamOptions& options,
87       const GURL& security_origin,
88       const MediaRequestResponseCallback& callback);
89
90   // GenerateStream opens new media devices according to |components|.  It
91   // creates a new request which is identified by a unique string that's
92   // returned to the caller.  |render_process_id| and |render_view_id| refer to
93   // the view where the infobar will appear to the user.
94   void GenerateStream(MediaStreamRequester* requester,
95                       int render_process_id,
96                       int render_view_id,
97                       const ResourceContext::SaltCallback& sc,
98                       int page_request_id,
99                       const StreamOptions& components,
100                       const GURL& security_origin,
101                       bool user_gesture);
102
103   void CancelRequest(int render_process_id,
104                      int render_view_id,
105                      int page_request_id);
106
107   // Cancel an open request identified by |label|.
108   virtual void CancelRequest(const std::string& label);
109
110   // Cancel all requests for the given |render_process_id|.
111   void CancelAllRequests(int render_process_id);
112
113   // Closes the stream device for a certain render view. The stream must have
114   // been opened by a call to GenerateStream.
115   void StopStreamDevice(int render_process_id,
116                         int render_view_id,
117                         const std::string& device_id);
118
119   // Gets a list of devices of |type|, which must be MEDIA_DEVICE_AUDIO_CAPTURE
120   // or MEDIA_DEVICE_VIDEO_CAPTURE.
121   // The request is identified using the string returned to the caller.
122   // When the |requester| is NULL, MediaStreamManager will enumerate both audio
123   // and video devices and also start monitoring device changes, such as
124   // plug/unplug. The new device lists will be delivered via media observer to
125   // MediaCaptureDevicesDispatcher.
126   virtual std::string EnumerateDevices(MediaStreamRequester* requester,
127                                        int render_process_id,
128                                        int render_view_id,
129                                        const ResourceContext::SaltCallback& sc,
130                                        int page_request_id,
131                                        MediaStreamType type,
132                                        const GURL& security_origin);
133
134   // Open a device identified by |device_id|.  |type| must be either
135   // MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
136   // The request is identified using string returned to the caller.
137   void OpenDevice(MediaStreamRequester* requester,
138                   int render_process_id,
139                   int render_view_id,
140                   const ResourceContext::SaltCallback& sc,
141                   int page_request_id,
142                   const std::string& device_id,
143                   MediaStreamType type,
144                   const GURL& security_origin);
145
146   // Called by UI to make sure the device monitor is started so that UI receive
147   // notifications about device changes.
148   void EnsureDeviceMonitorStarted();
149
150   // Implements MediaStreamProviderListener.
151   virtual void Opened(MediaStreamType stream_type,
152                       int capture_session_id) OVERRIDE;
153   virtual void Closed(MediaStreamType stream_type,
154                       int capture_session_id) OVERRIDE;
155   virtual void DevicesEnumerated(MediaStreamType stream_type,
156                                  const StreamDeviceInfoArray& devices) OVERRIDE;
157
158   // Implements base::SystemMonitor::DevicesChangedObserver.
159   virtual void OnDevicesChanged(
160       base::SystemMonitor::DeviceType device_type) OVERRIDE;
161
162   // Used by unit test to make sure fake devices are used instead of a real
163   // devices, which is needed for server based testing or certain tests (which
164   // can pass --use-fake-device-for-media-stream).
165   void UseFakeDevice();
166
167   // Called by the tests to specify a fake UI that should be used for next
168   // generated stream (or when using --use-fake-ui-for-media-stream).
169   void UseFakeUI(scoped_ptr<FakeMediaStreamUIProxy> fake_ui);
170
171   // Returns all devices currently opened by a request with label |label|.
172   // If no request with |label| exist, an empty array is returned.
173   StreamDeviceInfoArray GetDevicesOpenedByRequest(
174       const std::string& label) const;
175
176   // This object gets deleted on the UI thread after the IO thread has been
177   // destroyed. So we need to know when IO thread is being destroyed so that
178   // we can delete VideoCaptureManager and AudioInputDeviceManager. Normally
179   // this is handled by
180   // base::MessageLoop::DestructionObserver::WillDestroyCurrentMessageLoop.
181   // But for some tests which use TestBrowserThreadBundle, we need to call
182   // WillDestroyCurrentMessageLoop explicitly because the notification happens
183   // too late. (see http://crbug.com/247525#c14).
184   virtual void WillDestroyCurrentMessageLoop() OVERRIDE;
185
186   // Sends log messages to the render process hosts whose corresponding render
187   // processes are making device requests, to be used by the
188   // webrtcLoggingPrivate API if requested.
189   void AddLogMessageOnIOThread(const std::string& message);
190
191   // Adds |message| to native logs for outstanding device requests, for use by
192   // render processes hosts whose corresponding render processes are requesting
193   // logging from webrtcLoggingPrivate API. Safe to call from any thread.
194   static void SendMessageToNativeLog(const std::string& message);
195
196  protected:
197   // Used for testing.
198   MediaStreamManager();
199
200  private:
201   // Contains all data needed to keep track of requests.
202   class DeviceRequest;
203
204   // Cache enumerated device list.
205   struct EnumerationCache {
206     EnumerationCache();
207     ~EnumerationCache();
208
209     bool valid;
210     StreamDeviceInfoArray devices;
211   };
212
213   typedef std::map<std::string, DeviceRequest*> DeviceRequests;
214
215   // Initializes the device managers on IO thread.  Auto-starts the device
216   // thread and registers this as a listener with the device managers.
217   void InitializeDeviceManagersOnIOThread();
218
219   // Helper for sending up-to-date device lists to media observer when a
220   // capture device is plugged in or unplugged.
221   void NotifyDevicesChanged(MediaStreamType stream_type,
222                             const StreamDeviceInfoArray& devices);
223
224   void HandleAccessRequestResponse(const std::string& label,
225                                    const MediaStreamDevices& devices,
226                                    content::MediaStreamRequestResult result);
227   void StopMediaStreamFromBrowser(const std::string& label);
228
229   void DoEnumerateDevices(const std::string& label);
230
231   // Helpers.
232   // Checks if all devices that was requested in the request identififed by
233   // |label| has been opened and set the request state accordingly.
234   void HandleRequestDone(const std::string& label,
235                          DeviceRequest* request);
236   // Stop the use of the device associated with |session_id| of type |type| in
237   // all |requests_|. The device is removed from the request. If a request
238   /// doesn't use any devices as a consequence, the request is deleted.
239   void StopDevice(MediaStreamType type, int session_id);
240   // Calls the correct capture manager and close the device with |session_id|.
241   // All requests that uses the device are updated.
242   void CloseDevice(MediaStreamType type, int session_id);
243   // Returns true if a request for devices has been completed and the devices
244   // has either been opened or an error has occurred.
245   bool RequestDone(const DeviceRequest& request) const;
246   MediaStreamProvider* GetDeviceManager(MediaStreamType stream_type);
247   void StartEnumeration(DeviceRequest* request);
248   std::string AddRequest(DeviceRequest* request);
249   DeviceRequest* FindRequest(const std::string& label) const;
250   void DeleteRequest(const std::string& label);
251   void ClearEnumerationCache(EnumerationCache* cache);
252   // Returns true if the |cache| is invalid, false if it's invalid or if
253   // the |stream_type| is MEDIA_NO_SERVICE.
254   // On Android, this function will always return true for
255   // MEDIA_DEVICE_AUDIO_CAPTURE since we don't have a SystemMonitor to tell
256   // us about audio device changes.
257   bool EnumerationRequired(EnumerationCache* cache, MediaStreamType type);
258   // Prepare the request with label |label| by starting device enumeration if
259   // needed.
260   void SetupRequest(const std::string& label);
261   // Prepare |request| of type MEDIA_DEVICE_AUDIO_CAPTURE and/or
262   // MEDIA_DEVICE_VIDEO_CAPTURE for being posted to the UI by parsing
263   // StreamOptions::Constraints for requested device IDs.
264   bool SetupDeviceCaptureRequest(DeviceRequest* request);
265   // Prepare |request| of type MEDIA_TAB_AUDIO_CAPTURE and/or
266   // MEDIA_TAB_VIDEO_CAPTURE for being posted to the UI by parsing
267   // StreamOptions::Constraints for requested tab capture IDs.
268   bool SetupTabCaptureRequest(DeviceRequest* request);
269   // Prepare |request| of type MEDIA_LOOPBACK_AUDIO_CAPTURE and/or
270   // MEDIA_DESKTOP_VIDEO_CAPTURE for being posted to the UI by parsing
271   // StreamOptions::Constraints for the requested desktop ID.
272   bool SetupScreenCaptureRequest(DeviceRequest* request);
273   // Called when a request has been setup and devices have been enumerated if
274   // needed.
275   void PostRequestToUI(const std::string& label, DeviceRequest* request);
276   // Returns true if a device with |device_id| has already been requested with
277   // a render procecss_id and render_view_id and type equal to the the values
278   // in |request|. If it has been requested, |device_info| contain information
279   // about the device.
280   bool FindExistingRequestedDeviceInfo(
281       const DeviceRequest& new_request,
282       const MediaStreamDevice& new_device_info,
283       StreamDeviceInfo* existing_device_info,
284       MediaRequestState* existing_request_state) const;
285
286   void FinalizeGenerateStream(const std::string& label,
287                               DeviceRequest* request);
288   void FinalizeRequestFailed(const std::string& label,
289                              DeviceRequest* request,
290                              content::MediaStreamRequestResult result);
291   void FinalizeOpenDevice(const std::string& label,
292                           DeviceRequest* request);
293   void FinalizeMediaAccessRequest(const std::string& label,
294                                   DeviceRequest* request,
295                                   const MediaStreamDevices& devices);
296   void FinalizeEnumerateDevices(const std::string& label,
297                                 DeviceRequest* request);
298
299   // This method is called when an audio or video device is plugged in or
300   // removed. It make sure all MediaStreams that use a removed device is
301   // stopped and that the render process is notified. |old_devices| is the list
302   // of previously available devices. |new_devices| is the new
303   // list of currently available devices.
304   void StopRemovedDevices(const StreamDeviceInfoArray& old_devices,
305                           const StreamDeviceInfoArray& new_devices);
306   // Helper method used by StopRemovedDevices to stop the use of a certain
307   // device.
308   void StopRemovedDevice(const MediaStreamDevice& device);
309
310   // Helpers to start and stop monitoring devices.
311   void StartMonitoring();
312   void StopMonitoring();
313 #if defined(OS_MACOSX)
314   void StartMonitoringOnUIThread();
315 #endif
316
317   // Finds the requested device id from constraints. The requested device type
318   // must be MEDIA_DEVICE_AUDIO_CAPTURE or MEDIA_DEVICE_VIDEO_CAPTURE.
319   bool GetRequestedDeviceCaptureId(const DeviceRequest* request,
320                                    MediaStreamType type,
321                                    std::string* device_id) const;
322
323   void TranslateDeviceIdToSourceId(DeviceRequest* request,
324                                    MediaStreamDevice* device);
325
326   // Helper method that sends log messages to the render process hosts whose
327   // corresponding render processes are in |render_process_ids|, to be used by
328   // the webrtcLoggingPrivate API if requested.
329   void AddLogMessageOnUIThread(const std::set<int>& render_process_ids,
330                                const std::string& message);
331
332   // Finds and returns the device id corresponding to the given
333   // |source_id|. Returns true if there was a raw device id that matched the
334   // given |source_id|, false if nothing matched it.
335   bool TranslateSourceIdToDeviceId(
336       MediaStreamType stream_type,
337       const ResourceContext::SaltCallback& rc,
338       const GURL& security_origin,
339       const std::string& source_id,
340       std::string* device_id) const;
341
342   // Handles the callback from MediaStreamUIProxy to receive the UI window id,
343   // used for excluding the notification window in desktop capturing.
344   void OnMediaStreamUIWindowId(MediaStreamType video_type,
345                                StreamDeviceInfoArray devices,
346                                gfx::NativeViewId window_id);
347
348   // Task runner shared by VideoCaptureManager and AudioInputDeviceManager.
349   // Note: Enumeration tasks may take seconds to complete so must never be run
350   // on any of the BrowserThreads (UI, IO, etc).  See http://crbug.com/256945.
351   scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
352
353   media::AudioManager* const audio_manager_;  // not owned
354   scoped_refptr<AudioInputDeviceManager> audio_input_device_manager_;
355   scoped_refptr<VideoCaptureManager> video_capture_manager_;
356
357   // Indicator of device monitoring state.
358   bool monitoring_started_;
359
360   // Stores most recently enumerated device lists. The cache is cleared when
361   // monitoring is stopped or there is no request for that type of device.
362   EnumerationCache audio_enumeration_cache_;
363   EnumerationCache video_enumeration_cache_;
364
365   // Keeps track of live enumeration commands sent to VideoCaptureManager or
366   // AudioInputDeviceManager, in order to only enumerate when necessary.
367   int active_enumeration_ref_count_[NUM_MEDIA_TYPES];
368
369   // All non-closed request. Must be accessed on IO thread.
370   DeviceRequests requests_;
371
372   // Hold a pointer to the IO loop to check we delete the device thread and
373   // managers on the right thread.
374   base::MessageLoop* io_loop_;
375
376   bool use_fake_ui_;
377   scoped_ptr<FakeMediaStreamUIProxy> fake_ui_;
378
379   DISALLOW_COPY_AND_ASSIGN(MediaStreamManager);
380 };
381
382 }  // namespace content
383
384 #endif  // CONTENT_BROWSER_RENDERER_HOST_MEDIA_MEDIA_STREAM_MANAGER_H_