| Index: media/audio/pulse/audio_manager_pulse.cc
|
| diff --git a/media/audio/pulse/audio_manager_pulse.cc b/media/audio/pulse/audio_manager_pulse.cc
|
| index d6e9543183a0f86c8130b1459f8cd6a65e54ef2d..3c733d92779dee4bdc81a478229242be234fa95d 100644
|
| --- a/media/audio/pulse/audio_manager_pulse.cc
|
| +++ b/media/audio/pulse/audio_manager_pulse.cc
|
| @@ -47,18 +47,11 @@ static const base::FilePath::CharType kPulseLib[] =
|
| FILE_PATH_LITERAL("libpulse.so.0");
|
| #endif
|
|
|
| -// static
|
| -AudioManager* AudioManagerPulse::Create(AudioLogFactory* audio_log_factory) {
|
| - scoped_ptr<AudioManagerPulse> ret(new AudioManagerPulse(audio_log_factory));
|
| - if (ret->Init())
|
| - return ret.release();
|
| -
|
| - DVLOG(1) << "PulseAudio is not available on the OS";
|
| - return NULL;
|
| -}
|
| -
|
| -AudioManagerPulse::AudioManagerPulse(AudioLogFactory* audio_log_factory)
|
| - : AudioManagerBase(audio_log_factory),
|
| +AudioManagerPulse::AudioManagerPulse(
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
|
| + const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner,
|
| + AudioLogFactory* audio_log_factory)
|
| + : AudioManagerBase(task_runner, worker_task_runner, audio_log_factory),
|
| input_mainloop_(NULL),
|
| input_context_(NULL),
|
| devices_(NULL),
|
| @@ -74,6 +67,63 @@ AudioManagerPulse::~AudioManagerPulse() {
|
| DestroyPulse();
|
| }
|
|
|
| +bool AudioManagerPulse::Init() {
|
| + DCHECK(!input_mainloop_);
|
| +
|
| +#if defined(DLOPEN_PULSEAUDIO)
|
| + StubPathMap paths;
|
| +
|
| + // Check if the pulse library is avialbale.
|
| + paths[kModulePulse].push_back(kPulseLib);
|
| + if (!InitializeStubs(paths)) {
|
| + VLOG(1) << "Failed on loading the Pulse library and symbols";
|
| + return false;
|
| + }
|
| +#endif // defined(DLOPEN_PULSEAUDIO)
|
| +
|
| + // Create a mainloop API and connect to the default server.
|
| + // The mainloop is the internal asynchronous API event loop.
|
| + input_mainloop_ = pa_threaded_mainloop_new();
|
| + if (!input_mainloop_)
|
| + return false;
|
| +
|
| + // Start the threaded mainloop.
|
| + if (pa_threaded_mainloop_start(input_mainloop_))
|
| + return false;
|
| +
|
| + // Lock the event loop object, effectively blocking the event loop thread
|
| + // from processing events. This is necessary.
|
| + AutoPulseLock auto_lock(input_mainloop_);
|
| +
|
| + pa_mainloop_api* pa_mainloop_api =
|
| + pa_threaded_mainloop_get_api(input_mainloop_);
|
| + input_context_ = pa_context_new(pa_mainloop_api, "Chrome input");
|
| + if (!input_context_)
|
| + return false;
|
| +
|
| + pa_context_set_state_callback(input_context_, &pulse::ContextStateCallback,
|
| + input_mainloop_);
|
| + if (pa_context_connect(input_context_, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL)) {
|
| + VLOG(1) << "Failed to connect to the context. Error: "
|
| + << pa_strerror(pa_context_errno(input_context_));
|
| + return false;
|
| + }
|
| +
|
| + // Wait until |input_context_| is ready. pa_threaded_mainloop_wait() must be
|
| + // called after pa_context_get_state() in case the context is already ready,
|
| + // otherwise pa_threaded_mainloop_wait() will hang indefinitely.
|
| + while (true) {
|
| + pa_context_state_t context_state = pa_context_get_state(input_context_);
|
| + if (!PA_CONTEXT_IS_GOOD(context_state))
|
| + return false;
|
| + if (context_state == PA_CONTEXT_READY)
|
| + break;
|
| + pa_threaded_mainloop_wait(input_mainloop_);
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| // Implementation of AudioManager.
|
| bool AudioManagerPulse::HasAudioOutputDevices() {
|
| AudioDeviceNames devices;
|
| @@ -217,63 +267,6 @@ int AudioManagerPulse::GetNativeSampleRate() {
|
| return native_input_sample_rate_;
|
| }
|
|
|
| -bool AudioManagerPulse::Init() {
|
| - DCHECK(!input_mainloop_);
|
| -
|
| -#if defined(DLOPEN_PULSEAUDIO)
|
| - StubPathMap paths;
|
| -
|
| - // Check if the pulse library is avialbale.
|
| - paths[kModulePulse].push_back(kPulseLib);
|
| - if (!InitializeStubs(paths)) {
|
| - VLOG(1) << "Failed on loading the Pulse library and symbols";
|
| - return false;
|
| - }
|
| -#endif // defined(DLOPEN_PULSEAUDIO)
|
| -
|
| - // Create a mainloop API and connect to the default server.
|
| - // The mainloop is the internal asynchronous API event loop.
|
| - input_mainloop_ = pa_threaded_mainloop_new();
|
| - if (!input_mainloop_)
|
| - return false;
|
| -
|
| - // Start the threaded mainloop.
|
| - if (pa_threaded_mainloop_start(input_mainloop_))
|
| - return false;
|
| -
|
| - // Lock the event loop object, effectively blocking the event loop thread
|
| - // from processing events. This is necessary.
|
| - AutoPulseLock auto_lock(input_mainloop_);
|
| -
|
| - pa_mainloop_api* pa_mainloop_api =
|
| - pa_threaded_mainloop_get_api(input_mainloop_);
|
| - input_context_ = pa_context_new(pa_mainloop_api, "Chrome input");
|
| - if (!input_context_)
|
| - return false;
|
| -
|
| - pa_context_set_state_callback(input_context_, &pulse::ContextStateCallback,
|
| - input_mainloop_);
|
| - if (pa_context_connect(input_context_, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL)) {
|
| - VLOG(1) << "Failed to connect to the context. Error: "
|
| - << pa_strerror(pa_context_errno(input_context_));
|
| - return false;
|
| - }
|
| -
|
| - // Wait until |input_context_| is ready. pa_threaded_mainloop_wait() must be
|
| - // called after pa_context_get_state() in case the context is already ready,
|
| - // otherwise pa_threaded_mainloop_wait() will hang indefinitely.
|
| - while (true) {
|
| - pa_context_state_t context_state = pa_context_get_state(input_context_);
|
| - if (!PA_CONTEXT_IS_GOOD(context_state))
|
| - return false;
|
| - if (context_state == PA_CONTEXT_READY)
|
| - break;
|
| - pa_threaded_mainloop_wait(input_mainloop_);
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| void AudioManagerPulse::DestroyPulse() {
|
| if (!input_mainloop_) {
|
| DCHECK(!input_context_);
|
|
|