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