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