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 #ifndef CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
      6 #define CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
      7 
      8 #include <deque>
      9 #include <list>
     10 #include <map>
     11 
     12 #include "base/callback.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/memory/singleton.h"
     15 #include "base/observer_list.h"
     16 #include "content/public/browser/media_observer.h"
     17 #include "content/public/browser/notification_observer.h"
     18 #include "content/public/browser/notification_registrar.h"
     19 #include "content/public/browser/web_contents_delegate.h"
     20 #include "content/public/common/media_stream_request.h"
     21 
     22 class AudioStreamIndicator;
     23 class DesktopStreamsRegistry;
     24 class MediaStreamCaptureIndicator;
     25 class Profile;
     26 
     27 namespace extensions {
     28 class Extension;
     29 }
     30 
     31 namespace user_prefs {
     32 class PrefRegistrySyncable;
     33 }
     34 
     35 // This singleton is used to receive updates about media events from the content
     36 // layer.
     37 class MediaCaptureDevicesDispatcher : public content::MediaObserver,
     38                                       public content::NotificationObserver {
     39  public:
     40   class Observer {
     41    public:
     42     // Handle an information update consisting of a up-to-date audio capture
     43     // device lists. This happens when a microphone is plugged in or unplugged.
     44     virtual void OnUpdateAudioDevices(
     45         const content::MediaStreamDevices& devices) {}
     46 
     47     // Handle an information update consisting of a up-to-date video capture
     48     // device lists. This happens when a camera is plugged in or unplugged.
     49     virtual void OnUpdateVideoDevices(
     50         const content::MediaStreamDevices& devices) {}
     51 
     52     // Handle an information update related to a media stream request.
     53     virtual void OnRequestUpdate(
     54         int render_process_id,
     55         int render_view_id,
     56         const content::MediaStreamDevice& device,
     57         const content::MediaRequestState state) {}
     58 
     59     // Handle an information update that a new stream is being created.
     60     virtual void OnCreatingAudioStream(int render_process_id,
     61                                        int render_view_id) {}
     62 
     63     virtual ~Observer() {}
     64   };
     65 
     66   static MediaCaptureDevicesDispatcher* GetInstance();
     67 
     68   // Registers the preferences related to Media Stream default devices.
     69   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
     70 
     71   // Methods for observers. Called on UI thread.
     72   // Observers should add themselves on construction and remove themselves
     73   // on destruction.
     74   void AddObserver(Observer* observer);
     75   void RemoveObserver(Observer* observer);
     76   const content::MediaStreamDevices& GetAudioCaptureDevices();
     77   const content::MediaStreamDevices& GetVideoCaptureDevices();
     78 
     79   // Method called from WebCapturerDelegate implementations to process access
     80   // requests. |extension| is set to NULL if request was made from a drive-by
     81   // page.
     82   void ProcessMediaAccessRequest(
     83       content::WebContents* web_contents,
     84       const content::MediaStreamRequest& request,
     85       const content::MediaResponseCallback& callback,
     86       const extensions::Extension* extension);
     87 
     88   // Helper to get the default devices which can be used by the media request.
     89   // Uses the first available devices if the default devices are not available.
     90   // If the return list is empty, it means there is no available device on the
     91   // OS.
     92   // Called on the UI thread.
     93   void GetDefaultDevicesForProfile(Profile* profile,
     94                                    bool audio,
     95                                    bool video,
     96                                    content::MediaStreamDevices* devices);
     97 
     98   // Helpers for picking particular requested devices, identified by raw id.
     99   // If the device requested is not available it will return NULL.
    100   const content::MediaStreamDevice*
    101   GetRequestedAudioDevice(const std::string& requested_audio_device_id);
    102   const content::MediaStreamDevice*
    103   GetRequestedVideoDevice(const std::string& requested_video_device_id);
    104 
    105   // Returns the first available audio or video device, or NULL if no devices
    106   // are available.
    107   const content::MediaStreamDevice* GetFirstAvailableAudioDevice();
    108   const content::MediaStreamDevice* GetFirstAvailableVideoDevice();
    109 
    110   // Unittests that do not require actual device enumeration should call this
    111   // API on the singleton. It is safe to call this multiple times on the
    112   // signleton.
    113   void DisableDeviceEnumerationForTesting();
    114 
    115   // Overridden from content::MediaObserver:
    116   virtual void OnAudioCaptureDevicesChanged(
    117       const content::MediaStreamDevices& devices) OVERRIDE;
    118   virtual void OnVideoCaptureDevicesChanged(
    119       const content::MediaStreamDevices& devices) OVERRIDE;
    120   virtual void OnMediaRequestStateChanged(
    121       int render_process_id,
    122       int render_view_id,
    123       int page_request_id,
    124       const content::MediaStreamDevice& device,
    125       content::MediaRequestState state) OVERRIDE;
    126   virtual void OnAudioStreamPlayingChanged(
    127       int render_process_id,
    128       int render_view_id,
    129       int stream_id,
    130       bool is_playing,
    131       float power_dBFS,
    132       bool clipped) OVERRIDE;
    133   virtual void OnCreatingAudioStream(int render_process_id,
    134                                      int render_view_id) OVERRIDE;
    135 
    136   scoped_refptr<MediaStreamCaptureIndicator> GetMediaStreamCaptureIndicator();
    137 
    138   scoped_refptr<AudioStreamIndicator> GetAudioStreamIndicator();
    139 
    140   DesktopStreamsRegistry* GetDesktopStreamsRegistry();
    141 
    142   bool IsDesktopCaptureInProgress();
    143 
    144  private:
    145   friend struct DefaultSingletonTraits<MediaCaptureDevicesDispatcher>;
    146 
    147   struct PendingAccessRequest {
    148     PendingAccessRequest(const content::MediaStreamRequest& request,
    149                          const content::MediaResponseCallback& callback);
    150     ~PendingAccessRequest();
    151 
    152     content::MediaStreamRequest request;
    153     content::MediaResponseCallback callback;
    154   };
    155   typedef std::deque<PendingAccessRequest> RequestsQueue;
    156   typedef std::map<content::WebContents*, RequestsQueue> RequestsQueues;
    157 
    158   MediaCaptureDevicesDispatcher();
    159   virtual ~MediaCaptureDevicesDispatcher();
    160 
    161   // content::NotificationObserver implementation.
    162   virtual void Observe(int type,
    163                        const content::NotificationSource& source,
    164                        const content::NotificationDetails& details) OVERRIDE;
    165 
    166   // Helpers for ProcessMediaAccessRequest().
    167   void ProcessDesktopCaptureAccessRequest(
    168       content::WebContents* web_contents,
    169       const content::MediaStreamRequest& request,
    170       const content::MediaResponseCallback& callback,
    171       const extensions::Extension* extension);
    172   void ProcessScreenCaptureAccessRequest(
    173       content::WebContents* web_contents,
    174       const content::MediaStreamRequest& request,
    175       const content::MediaResponseCallback& callback,
    176       const extensions::Extension* extension);
    177   void ProcessTabCaptureAccessRequest(
    178       content::WebContents* web_contents,
    179       const content::MediaStreamRequest& request,
    180       const content::MediaResponseCallback& callback,
    181       const extensions::Extension* extension);
    182   void ProcessMediaAccessRequestFromPlatformAppOrExtension(
    183       content::WebContents* web_contents,
    184       const content::MediaStreamRequest& request,
    185       const content::MediaResponseCallback& callback,
    186       const extensions::Extension* extension);
    187   void ProcessRegularMediaAccessRequest(
    188       content::WebContents* web_contents,
    189       const content::MediaStreamRequest& request,
    190       const content::MediaResponseCallback& callback);
    191   void ProcessQueuedAccessRequest(content::WebContents* web_contents);
    192   void OnAccessRequestResponse(content::WebContents* web_contents,
    193                                const content::MediaStreamDevices& devices,
    194                                scoped_ptr<content::MediaStreamUI> ui);
    195 
    196   // Called by the MediaObserver() functions, executed on UI thread.
    197   void UpdateAudioDevicesOnUIThread(const content::MediaStreamDevices& devices);
    198   void UpdateVideoDevicesOnUIThread(const content::MediaStreamDevices& devices);
    199   void UpdateMediaRequestStateOnUIThread(
    200       int render_process_id,
    201       int render_view_id,
    202       int page_request_id,
    203       const content::MediaStreamDevice& device,
    204       content::MediaRequestState state);
    205   void OnCreatingAudioStreamOnUIThread(int render_process_id,
    206                                        int render_view_id);
    207 
    208   // A list of cached audio capture devices.
    209   content::MediaStreamDevices audio_devices_;
    210 
    211   // A list of cached video capture devices.
    212   content::MediaStreamDevices video_devices_;
    213 
    214   // A list of observers for the device update notifications.
    215   ObserverList<Observer> observers_;
    216 
    217   // Flag to indicate if device enumeration has been done/doing.
    218   // Only accessed on UI thread.
    219   bool devices_enumerated_;
    220 
    221   // Flag used by unittests to disable device enumeration.
    222   bool is_device_enumeration_disabled_;
    223 
    224   RequestsQueues pending_requests_;
    225 
    226   scoped_refptr<MediaStreamCaptureIndicator> media_stream_capture_indicator_;
    227 
    228   scoped_refptr<AudioStreamIndicator> audio_stream_indicator_;
    229 
    230   scoped_ptr<DesktopStreamsRegistry> desktop_streams_registry_;
    231 
    232   content::NotificationRegistrar notifications_registrar_;
    233 
    234   // Tracks MEDIA_DESKTOP_VIDEO_CAPTURE sessions which reach the
    235   // MEDIA_REQUEST_STATE_DONE state.  Sessions are remove when
    236   // MEDIA_REQUEST_STATE_CLOSING is encountered.
    237   struct DesktopCaptureSession {
    238     int render_process_id;
    239     int render_view_id;
    240     int page_request_id;
    241   };
    242   typedef std::list<DesktopCaptureSession> DesktopCaptureSessions;
    243   DesktopCaptureSessions desktop_capture_sessions_;
    244 
    245   DISALLOW_COPY_AND_ASSIGN(MediaCaptureDevicesDispatcher);
    246 };
    247 
    248 #endif  // CHROME_BROWSER_MEDIA_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
    249