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