webrtc_audio_private_api.h revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
11e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
21e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
31e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// found in the LICENSE file.
41e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
51e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#ifndef CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
61e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#define CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
71e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/memory/ref_counted.h"
91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/system_monitor/system_monitor.h"
101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_function.h"
121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/common/extensions/api/webrtc_audio_private.h"
141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "media/audio/audio_device_name.h"
161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "url/gurl.h"
171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace base {
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class MessageLoopProxy;
201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)namespace extensions {
231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Listens for device changes and forwards as an extension event.
251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class WebrtcAudioPrivateEventService
261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : public ProfileKeyedAPI,
271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      public base::SystemMonitor::DevicesChangedObserver {
281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public:
291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  explicit WebrtcAudioPrivateEventService(Profile* profile);
301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual ~WebrtcAudioPrivateEventService();
311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // ProfileKeyedAPI implementation.
331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void Shutdown() OVERRIDE;
341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static ProfileKeyedAPIFactory<WebrtcAudioPrivateEventService>*
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      GetFactoryInstance();
361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  static const char* service_name();
371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // base::SystemMonitor::DevicesChangedObserver implementation.
391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void OnDevicesChanged(
401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::SystemMonitor::DeviceType device_type) OVERRIDE;
411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  friend class ProfileKeyedAPIFactory<WebrtcAudioPrivateEventService>;
441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void SignalEvent();
461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Profile* profile_;
481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class WebrtcAudioPrivateGetSinksFunction : public ChromeAsyncExtensionFunction {
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) protected:
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual ~WebrtcAudioPrivateGetSinksFunction() {}
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getSinks",
561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             WEBRTC_AUDIO_PRIVATE_GET_SINKS);
571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual bool RunImpl() OVERRIDE;
591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void DoQuery();
601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void DoneOnUIThread();
611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Common base for functions that start by retrieving the list of
641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// controllers for the specified tab.
651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class WebrtcAudioPrivateTabIdFunction : public ChromeAsyncExtensionFunction {
661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) protected:
671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual ~WebrtcAudioPrivateTabIdFunction() {}
681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) protected:
701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  bool DoRunImpl(int tab_id);
711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void OnControllerList(
721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const content::RenderViewHost::AudioOutputControllerList& list) = 0;
731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class WebrtcAudioPrivateGetActiveSinkFunction
761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : public WebrtcAudioPrivateTabIdFunction {
771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) protected:
781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual ~WebrtcAudioPrivateGetActiveSinkFunction() {}
791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getActiveSink",
821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             WEBRTC_AUDIO_PRIVATE_GET_ACTIVE_SINK);
831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual bool RunImpl() OVERRIDE;
851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void OnControllerList(
861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const content::RenderViewHost::AudioOutputControllerList&
871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      controllers) OVERRIDE;
881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void OnSinkId(const std::string&);
891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class WebrtcAudioPrivateSetActiveSinkFunction
921e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : public WebrtcAudioPrivateTabIdFunction {
931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) public:
941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  WebrtcAudioPrivateSetActiveSinkFunction();
951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) protected:
971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual ~WebrtcAudioPrivateSetActiveSinkFunction();
981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
1001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.setActiveSink",
1011e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             WEBRTC_AUDIO_PRIVATE_SET_ACTIVE_SINK);
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual bool RunImpl() OVERRIDE;
1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual void OnControllerList(
1051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const content::RenderViewHost::AudioOutputControllerList&
1061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      controllers) OVERRIDE;
1071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void SwitchDone();
1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  void DoneOnUIThread();
1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Message loop of the thread this class is constructed on.
1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const scoped_refptr<base::MessageLoopProxy> message_loop_;
1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  int tab_id_;
1141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  std::string sink_id_;
1151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Number of sink IDs we are still waiting for. Can become greater
1171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // than 0 in OnControllerList, decreases on every OnSinkId call.
1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  size_t num_remaining_sink_ids_;
1191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)class WebrtcAudioPrivateGetAssociatedSinkFunction
1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    : public ChromeAsyncExtensionFunction {
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) public:
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  WebrtcAudioPrivateGetAssociatedSinkFunction();
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) protected:
1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual ~WebrtcAudioPrivateGetAssociatedSinkFunction();
1281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) private:
1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  DECLARE_EXTENSION_FUNCTION("webrtcAudioPrivate.getAssociatedSink",
1311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                             WEBRTC_AUDIO_PRIVATE_GET_ASSOCIATED_SINK);
1321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual bool RunImpl() OVERRIDE;
1341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // This implementation is slightly complicated because of different
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // thread requirements for the various functions we need to invoke.
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //
138a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // All OnXyzDone callbacks occur on the UI thread, and they trigger
139a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the next step (or send the response in case of the last step).
140a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // The sequence of events is:
142a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // 1. Get the list of source devices on the device thread.
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // 2. Given a source ID for an origin and that security origin, find
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //    the raw source ID. This needs to happen on the IO thread since
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //    we will be using the ResourceContext.
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // 3. Given a raw source ID, get the associated sink ID on the
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  //    device thread.
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Fills in |source_devices_|. OnGetDevicesDone will be invoked on
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // the UI thread once done.
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void GetDevicesOnDeviceThread();
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void OnGetDevicesDone();
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Takes the parameters of the function, returns the raw source
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // device ID, or the empty string if none.
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string GetRawSourceIDOnIOThread(content::ResourceContext* context,
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       GURL security_origin,
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                       const std::string& source_id_in_origin);
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void OnGetRawSourceIDDone(const std::string& raw_source_id);
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Given a raw source ID, get its associated sink, which needs to
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // happen on the device thread.
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::string GetAssociatedSinkOnDeviceThread(const std::string& raw_source_id);
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void OnGetAssociatedSinkDone(const std::string& associated_sink_id);
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Accessed from UI thread and device thread, but only on one at a
167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // time, no locking needed.
168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<api::webrtc_audio_private::GetAssociatedSink::Params> params_;
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Filled in by DoWorkOnDeviceThread.
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  media::AudioDeviceNames source_devices_;
1721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
1731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}  // namespace extensions
1751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
1761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#endif  // CHROME_BROWSER_EXTENSIONS_API_WEBRTC_AUDIO_PRIVATE_WEBRTC_AUDIO_PRIVATE_API_H_
177