Chromium Code Reviews| 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..71a24d900d34a3f5f205fa2b67a22ab9f2826092 100644 |
| --- a/media/audio/pulse/audio_manager_pulse.cc |
| +++ b/media/audio/pulse/audio_manager_pulse.cc |
| @@ -47,18 +47,13 @@ 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( |
| + scoped_refptr<base::SingleThreadTaskRunner> task_runner, |
| + scoped_refptr<base::SingleThreadTaskRunner> worker_task_runner, |
| + AudioLogFactory* audio_log_factory) |
| + : AudioManagerBase(std::move(task_runner), |
| + std::move(worker_task_runner), |
| + audio_log_factory), |
| input_mainloop_(NULL), |
| input_context_(NULL), |
| devices_(NULL), |
| @@ -74,6 +69,63 @@ AudioManagerPulse::~AudioManagerPulse() { |
| DestroyPulse(); |
|
alokp
2016/04/05 23:57:40
I think we need to Shutdown AudioManagerBase, whic
DaleCurtis
2016/04/06 01:22:29
Can we just post a task to a static DestroyPulse m
alokp
2016/04/06 02:03:44
Yup.. thats exactly what I am doing..
|
| } |
| +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 +269,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_); |