Home | History | Annotate | Download | only in webrtc_audio_private
      1 // Copyright 2013 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_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
      6 #define CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
      7 
      8 #include "base/memory/ref_counted.h"
      9 #include "base/system_monitor/system_monitor.h"
     10 #include "chrome/browser/extensions/chrome_extension_function.h"
     11 #include "chrome/common/extensions/api/webrtc_audio_private.h"
     12 #include "content/public/browser/render_view_host.h"
     13 #include "extensions/browser/browser_context_keyed_api_factory.h"
     14 #include "media/audio/audio_device_name.h"
     15 #include "url/gurl.h"
     16 
     17 namespace content {
     18 class ResourceContext;
     19 }
     20 
     21 namespace extensions {
     22 
     23 // Listens for device changes and forwards as an extension event.
     24 class WebrtcAudioPrivateEventService
     25     : public BrowserContextKeyedAPI,
     26       public base::SystemMonitor::DevicesChangedObserver {
     27  public:
     28   explicit WebrtcAudioPrivateEventService(content::BrowserContext* context);
     29   virtual ~WebrtcAudioPrivateEventService();
     30 
     31   // BrowserContextKeyedAPI implementation.
     32   virtual void Shutdown() OVERRIDE;
     33   static BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService>*
     34       GetFactoryInstance();
     35   static const char* service_name();
     36 
     37   // base::SystemMonitor::DevicesChangedObserver implementation.
     38   virtual void OnDevicesChanged(
     39       base::SystemMonitor::DeviceType device_type) OVERRIDE;
     40 
     41  private:
     42   friend class BrowserContextKeyedAPIFactory<WebrtcAudioPrivateEventService>;
     43 
     44   void SignalEvent();
     45 
     46   content::BrowserContext* browser_context_;
     47 };
     48 
     49 // Common base for WebrtcAudioPrivate functions, that provides a
     50 // couple of optionally-used common implementations.
     51 class WebrtcAudioPrivateFunction : public ChromeAsyncExtensionFunction {
     52  protected:
     53   WebrtcAudioPrivateFunction();
     54   virtual ~WebrtcAudioPrivateFunction();
     55 
     56  protected:
     57   // Retrieves the list of output device names on the appropriate
     58   // thread. Call from UI thread, callback will occur on IO thread.
     59   void GetOutputDeviceNames();
     60 
     61   // Must override this if you call GetOutputDeviceNames. Called on IO thread.
     62   virtual void OnOutputDeviceNames(
     63       scoped_ptr<media::AudioDeviceNames> device_names);
     64 
     65   // Retrieve the list of AudioOutputController objects. Calls back
     66   // via OnControllerList.
     67   //
     68   // Returns false on error, in which case it has set |error_| and the
     69   // entire function should fail.
     70   //
     71   // Call from any thread. Callback will occur on originating thread.
     72   bool GetControllerList(int tab_id);
     73 
     74   // Must override this if you call GetControllerList.
     75   virtual void OnControllerList(
     76       const content::RenderViewHost::AudioOutputControllerList& list);
     77 
     78   // Calculates a single HMAC. Call from any thread. Calls back via
     79   // OnHMACCalculated on UI thread.
     80   //
     81   // This function, and device ID HMACs in this API in general use the
     82   // calling extension's ID as the security origin. The only exception
     83   // to this rule is when calculating the input device ID HMAC in
     84   // getAssociatedSink, where we use the provided |securityOrigin|.
     85   void CalculateHMAC(const std::string& raw_id);
     86 
     87   // Must override this if you call CalculateHMAC.
     88   virtual void OnHMACCalculated(const std::string& hmac);
     89 
     90   // Calculates a single HMAC, using the extension ID as the security origin.
     91   //
     92   // Call only on IO thread.
     93   std::string CalculateHMACImpl(const std::string& raw_id);
     94 
     95   // Initializes |resource_context_|. Must be called on the UI thread,
     96   // before any calls to |resource_context()|.
     97   void InitResourceContext();
     98 
     99   // Callable from any thread. Must previously have called
    100   // |InitResourceContext()|.
    101   content::ResourceContext* resource_context() const;
    102 
    103  private:
    104   content::ResourceContext* resource_context_;
    105 
    106   DISALLOW_COPY_AND_ASSIGN(WebrtcAudioPrivateFunction);
    107 };
    108 
    109 class WebrtcAudioPrivateGetSinksFunction : public WebrtcAudioPrivateFunction {
    110  protected:
    111   virtual ~WebrtcAudioPrivateGetSinksFunction() {}
    112 
    113  private:
    114   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getSinks",
    115                              WEBRTC_AUDIO_PRIVATE_GET_SINKS);
    116 
    117   // Sequence of events is that we query the list of sinks on the
    118   // AudioManager's thread, then calculate HMACs on the IO thread,
    119   // then finish on the UI thread.
    120   virtual bool RunAsync() OVERRIDE;
    121   void DoQuery();
    122   virtual void OnOutputDeviceNames(
    123       scoped_ptr<media::AudioDeviceNames> raw_ids) OVERRIDE;
    124   void DoneOnUIThread();
    125 };
    126 
    127 class WebrtcAudioPrivateGetActiveSinkFunction
    128     : public WebrtcAudioPrivateFunction {
    129  protected:
    130   virtual ~WebrtcAudioPrivateGetActiveSinkFunction() {}
    131 
    132  private:
    133   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getActiveSink",
    134                              WEBRTC_AUDIO_PRIVATE_GET_ACTIVE_SINK);
    135 
    136   virtual bool RunAsync() OVERRIDE;
    137   virtual void OnControllerList(
    138       const content::RenderViewHost::AudioOutputControllerList&
    139       controllers) OVERRIDE;
    140   virtual void OnHMACCalculated(const std::string& hmac) OVERRIDE;
    141 };
    142 
    143 class WebrtcAudioPrivateSetActiveSinkFunction
    144     : public WebrtcAudioPrivateFunction {
    145  public:
    146   WebrtcAudioPrivateSetActiveSinkFunction();
    147 
    148  protected:
    149   virtual ~WebrtcAudioPrivateSetActiveSinkFunction();
    150 
    151  private:
    152   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.setActiveSink",
    153                              WEBRTC_AUDIO_PRIVATE_SET_ACTIVE_SINK);
    154 
    155   virtual bool RunAsync() OVERRIDE;
    156   virtual void OnControllerList(
    157       const content::RenderViewHost::AudioOutputControllerList&
    158       controllers) OVERRIDE;
    159   virtual void OnOutputDeviceNames(
    160       scoped_ptr<media::AudioDeviceNames> device_names) OVERRIDE;
    161   void SwitchDone();
    162   void DoneOnUIThread();
    163 
    164   int tab_id_;
    165   std::string sink_id_;
    166 
    167   // Filled in by OnControllerList.
    168   content::RenderViewHost::AudioOutputControllerList controllers_;
    169 
    170   // Number of sink IDs we are still waiting for. Can become greater
    171   // than 0 in OnControllerList, decreases on every OnSinkId call.
    172   size_t num_remaining_sink_ids_;
    173 };
    174 
    175 class WebrtcAudioPrivateGetAssociatedSinkFunction
    176     : public WebrtcAudioPrivateFunction {
    177  public:
    178   WebrtcAudioPrivateGetAssociatedSinkFunction();
    179 
    180  protected:
    181   virtual ~WebrtcAudioPrivateGetAssociatedSinkFunction();
    182 
    183  private:
    184   DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getAssociatedSink",
    185                              WEBRTC_AUDIO_PRIVATE_GET_ASSOCIATED_SINK);
    186 
    187   virtual bool RunAsync() OVERRIDE;
    188 
    189   // This implementation is slightly complicated because of different
    190   // thread requirements for the various functions we need to invoke.
    191   //
    192   // Each worker function will post a task to the appropriate thread
    193   // for the next one.
    194   //
    195   // The sequence of events is:
    196   // 1. Get the list of source devices on the device thread.
    197   // 2. Given a source ID for an origin and that security origin, find
    198   //    the raw source ID. This needs to happen on the IO thread since
    199   //    we will be using the ResourceContext.
    200   // 3. Given a raw source ID, get the raw associated sink ID on the
    201   //    device thread.
    202   // 4. Given the raw associated sink ID, get its HMAC on the IO thread.
    203   // 5. Respond with the HMAC of the associated sink ID on the UI thread.
    204 
    205   // Fills in |source_devices_|. Note that these are input devices,
    206   // not output devices, so don't use
    207   // |WebrtcAudioPrivateFunction::GetOutputDeviceNames|.
    208   void GetDevicesOnDeviceThread();
    209 
    210   // Takes the parameters of the function, retrieves the raw source
    211   // device ID, or the empty string if none.
    212   void GetRawSourceIDOnIOThread();
    213 
    214   // Gets the raw sink ID for a raw source ID. Sends it to |CalculateHMAC|.
    215   void GetAssociatedSinkOnDeviceThread(const std::string& raw_source_id);
    216 
    217   // Receives the associated sink ID after its HMAC is calculated.
    218   virtual void OnHMACCalculated(const std::string& hmac) OVERRIDE;
    219 
    220   // Accessed from UI thread and device thread, but only on one at a
    221   // time, no locking needed.
    222   scoped_ptr<api::webrtc_audio_private::GetAssociatedSink::Params> params_;
    223 
    224   // Audio sources (input devices). Filled in by DoWorkOnDeviceThread.
    225   media::AudioDeviceNames source_devices_;
    226 };
    227 
    228 }  // namespace extensions
    229 
    230 #endif  // CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
    231