Home | History | Annotate | Download | only in media
      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 
     38 namespace base {
     39 class Thread;
     40 }
     41 
     42 namespace media {
     43 class AudioManager;
     44 }
     45 
     46 namespace content {
     47 
     48 class AudioInputDeviceManager;
     49 class FakeMediaStreamUIProxy;
     50 class MediaStreamDeviceSettings;
     51 class MediaStreamRequester;
     52 class MediaStreamUIProxy;
     53 class 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.
     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. |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