/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <assert.h>

#include "webrtc/modules/audio_device/audio_device_config.h"
#include "webrtc/modules/audio_device/linux/audio_device_pulse_linux.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/logging.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"

webrtc::adm_linux_pulse::PulseAudioSymbolTable PaSymbolTable;

// Accesses Pulse functions through our late-binding symbol table instead of
// directly. This way we don't have to link to libpulse, which means our binary
// will work on systems that don't have it.
#define LATE(sym)                                                             \
  LATESYM_GET(webrtc::adm_linux_pulse::PulseAudioSymbolTable, &PaSymbolTable, \
              sym)

namespace webrtc {

AudioDeviceLinuxPulse::AudioDeviceLinuxPulse()
    : _ptrAudioBuffer(NULL),
      _timeEventRec(*EventWrapper::Create()),
      _timeEventPlay(*EventWrapper::Create()),
      _recStartEvent(*EventWrapper::Create()),
      _playStartEvent(*EventWrapper::Create()),
      _inputDeviceIndex(0),
      _outputDeviceIndex(0),
      _inputDeviceIsSpecified(false),
      _outputDeviceIsSpecified(false),
      sample_rate_hz_(0),
      _recChannels(1),
      _playChannels(1),
      _initialized(false),
      _recording(false),
      _playing(false),
      _recIsInitialized(false),
      _playIsInitialized(false),
      _startRec(false),
      _stopRec(false),
      _startPlay(false),
      _stopPlay(false),
      _AGC(false),
      update_speaker_volume_at_startup_(false),
      _sndCardPlayDelay(0),
      _sndCardRecDelay(0),
      _writeErrors(0),
      _playWarning(0),
      _playError(0),
      _recWarning(0),
      _recError(0),
      _deviceIndex(-1),
      _numPlayDevices(0),
      _numRecDevices(0),
      _playDeviceName(NULL),
      _recDeviceName(NULL),
      _playDisplayDeviceName(NULL),
      _recDisplayDeviceName(NULL),
      _playBuffer(NULL),
      _playbackBufferSize(0),
      _playbackBufferUnused(0),
      _tempBufferSpace(0),
      _recBuffer(NULL),
      _recordBufferSize(0),
      _recordBufferUsed(0),
      _tempSampleData(NULL),
      _tempSampleDataSize(0),
      _configuredLatencyPlay(0),
      _configuredLatencyRec(0),
      _paDeviceIndex(-1),
      _paStateChanged(false),
      _paMainloop(NULL),
      _paMainloopApi(NULL),
      _paContext(NULL),
      _recStream(NULL),
      _playStream(NULL),
      _recStreamFlags(0),
      _playStreamFlags(0) {
  LOG(LS_INFO) << __FUNCTION__ << " created";

  memset(_paServerVersion, 0, sizeof(_paServerVersion));
  memset(&_playBufferAttr, 0, sizeof(_playBufferAttr));
  memset(&_recBufferAttr, 0, sizeof(_recBufferAttr));
  memset(_oldKeyState, 0, sizeof(_oldKeyState));
}

AudioDeviceLinuxPulse::~AudioDeviceLinuxPulse() {
  LOG(LS_INFO) << __FUNCTION__ << " destroyed";
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  Terminate();

  if (_recBuffer) {
    delete[] _recBuffer;
    _recBuffer = NULL;
  }
  if (_playBuffer) {
    delete[] _playBuffer;
    _playBuffer = NULL;
  }
  if (_playDeviceName) {
    delete[] _playDeviceName;
    _playDeviceName = NULL;
  }
  if (_recDeviceName) {
    delete[] _recDeviceName;
    _recDeviceName = NULL;
  }

  delete &_recStartEvent;
  delete &_playStartEvent;
  delete &_timeEventRec;
  delete &_timeEventPlay;
}

void AudioDeviceLinuxPulse::AttachAudioBuffer(AudioDeviceBuffer* audioBuffer) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());

  _ptrAudioBuffer = audioBuffer;

  // Inform the AudioBuffer about default settings for this implementation.
  // Set all values to zero here since the actual settings will be done by
  // InitPlayout and InitRecording later.
  _ptrAudioBuffer->SetRecordingSampleRate(0);
  _ptrAudioBuffer->SetPlayoutSampleRate(0);
  _ptrAudioBuffer->SetRecordingChannels(0);
  _ptrAudioBuffer->SetPlayoutChannels(0);
}

// ----------------------------------------------------------------------------
//  ActiveAudioLayer
// ----------------------------------------------------------------------------

int32_t AudioDeviceLinuxPulse::ActiveAudioLayer(
    AudioDeviceModule::AudioLayer& audioLayer) const {
  audioLayer = AudioDeviceModule::kLinuxPulseAudio;
  return 0;
}

AudioDeviceGeneric::InitStatus AudioDeviceLinuxPulse::Init() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_initialized) {
    return InitStatus::OK;
  }

  // Initialize PulseAudio
  if (InitPulseAudio() < 0) {
    LOG(LS_ERROR) << "failed to initialize PulseAudio";
    if (TerminatePulseAudio() < 0) {
      LOG(LS_ERROR) << "failed to terminate PulseAudio";
    }
    return InitStatus::OTHER_ERROR;
  }

  _playWarning = 0;
  _playError = 0;
  _recWarning = 0;
  _recError = 0;

  // Get X display handle for typing detection
  _XDisplay = XOpenDisplay(NULL);
  if (!_XDisplay) {
    LOG(LS_WARNING)
        << "failed to open X display, typing detection will not work";
  }

  // RECORDING
  _ptrThreadRec.reset(new rtc::PlatformThread(
      RecThreadFunc, this, "webrtc_audio_module_rec_thread"));

  _ptrThreadRec->Start();
  _ptrThreadRec->SetPriority(rtc::kRealtimePriority);

  // PLAYOUT
  _ptrThreadPlay.reset(new rtc::PlatformThread(
      PlayThreadFunc, this, "webrtc_audio_module_play_thread"));
  _ptrThreadPlay->Start();
  _ptrThreadPlay->SetPriority(rtc::kRealtimePriority);

  _initialized = true;

  return InitStatus::OK;
}

int32_t AudioDeviceLinuxPulse::Terminate() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (!_initialized) {
    return 0;
  }

  _mixerManager.Close();

  // RECORDING
  if (_ptrThreadRec) {
    rtc::PlatformThread* tmpThread = _ptrThreadRec.release();

    _timeEventRec.Set();
    tmpThread->Stop();
    delete tmpThread;
  }

  // PLAYOUT
  if (_ptrThreadPlay) {
    rtc::PlatformThread* tmpThread = _ptrThreadPlay.release();

    _timeEventPlay.Set();
    tmpThread->Stop();
    delete tmpThread;
  }

  // Terminate PulseAudio
  if (TerminatePulseAudio() < 0) {
    LOG(LS_ERROR) << "failed to terminate PulseAudio";
    return -1;
  }

  if (_XDisplay) {
    XCloseDisplay(_XDisplay);
    _XDisplay = NULL;
  }

  _initialized = false;
  _outputDeviceIsSpecified = false;
  _inputDeviceIsSpecified = false;

  return 0;
}

bool AudioDeviceLinuxPulse::Initialized() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_initialized);
}

int32_t AudioDeviceLinuxPulse::InitSpeaker() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());

  if (_playing) {
    return -1;
  }

  if (!_outputDeviceIsSpecified) {
    return -1;
  }

  // check if default device
  if (_outputDeviceIndex == 0) {
    uint16_t deviceIndex = 0;
    GetDefaultDeviceInfo(false, NULL, deviceIndex);
    _paDeviceIndex = deviceIndex;
  } else {
    // get the PA device index from
    // the callback
    _deviceIndex = _outputDeviceIndex;

    // get playout devices
    PlayoutDevices();
  }

  // the callback has now set the _paDeviceIndex to
  // the PulseAudio index of the device
  if (_mixerManager.OpenSpeaker(_paDeviceIndex) == -1) {
    return -1;
  }

  // clear _deviceIndex
  _deviceIndex = -1;
  _paDeviceIndex = -1;

  return 0;
}

int32_t AudioDeviceLinuxPulse::InitMicrophone() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_recording) {
    return -1;
  }

  if (!_inputDeviceIsSpecified) {
    return -1;
  }

  // Check if default device
  if (_inputDeviceIndex == 0) {
    uint16_t deviceIndex = 0;
    GetDefaultDeviceInfo(true, NULL, deviceIndex);
    _paDeviceIndex = deviceIndex;
  } else {
    // Get the PA device index from
    // the callback
    _deviceIndex = _inputDeviceIndex;

    // get recording devices
    RecordingDevices();
  }

  // The callback has now set the _paDeviceIndex to
  // the PulseAudio index of the device
  if (_mixerManager.OpenMicrophone(_paDeviceIndex) == -1) {
    return -1;
  }

  // Clear _deviceIndex
  _deviceIndex = -1;
  _paDeviceIndex = -1;

  return 0;
}

bool AudioDeviceLinuxPulse::SpeakerIsInitialized() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_mixerManager.SpeakerIsInitialized());
}

bool AudioDeviceLinuxPulse::MicrophoneIsInitialized() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_mixerManager.MicrophoneIsInitialized());
}

int32_t AudioDeviceLinuxPulse::SpeakerVolumeIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  bool wasInitialized = _mixerManager.SpeakerIsInitialized();

  // Make an attempt to open up the
  // output mixer corresponding to the currently selected output device.
  if (!wasInitialized && InitSpeaker() == -1) {
    // If we end up here it means that the selected speaker has no volume
    // control.
    available = false;
    return 0;
  }

  // Given that InitSpeaker was successful, we know volume control exists.
  available = true;

  // Close the initialized output mixer
  if (!wasInitialized) {
    _mixerManager.CloseSpeaker();
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::SetSpeakerVolume(uint32_t volume) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (!_playing) {
    // Only update the volume if it's been set while we weren't playing.
    update_speaker_volume_at_startup_ = true;
  }
  return (_mixerManager.SetSpeakerVolume(volume));
}

int32_t AudioDeviceLinuxPulse::SpeakerVolume(uint32_t& volume) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  uint32_t level(0);

  if (_mixerManager.SpeakerVolume(level) == -1) {
    return -1;
  }

  volume = level;

  return 0;
}

int32_t AudioDeviceLinuxPulse::MaxSpeakerVolume(uint32_t& maxVolume) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  uint32_t maxVol(0);

  if (_mixerManager.MaxSpeakerVolume(maxVol) == -1) {
    return -1;
  }

  maxVolume = maxVol;

  return 0;
}

int32_t AudioDeviceLinuxPulse::MinSpeakerVolume(uint32_t& minVolume) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  uint32_t minVol(0);

  if (_mixerManager.MinSpeakerVolume(minVol) == -1) {
    return -1;
  }

  minVolume = minVol;

  return 0;
}

int32_t AudioDeviceLinuxPulse::SpeakerMuteIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  bool isAvailable(false);
  bool wasInitialized = _mixerManager.SpeakerIsInitialized();

  // Make an attempt to open up the
  // output mixer corresponding to the currently selected output device.
  //
  if (!wasInitialized && InitSpeaker() == -1) {
    // If we end up here it means that the selected speaker has no volume
    // control, hence it is safe to state that there is no mute control
    // already at this stage.
    available = false;
    return 0;
  }

  // Check if the selected speaker has a mute control
  _mixerManager.SpeakerMuteIsAvailable(isAvailable);

  available = isAvailable;

  // Close the initialized output mixer
  if (!wasInitialized) {
    _mixerManager.CloseSpeaker();
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::SetSpeakerMute(bool enable) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_mixerManager.SetSpeakerMute(enable));
}

int32_t AudioDeviceLinuxPulse::SpeakerMute(bool& enabled) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  bool muted(0);
  if (_mixerManager.SpeakerMute(muted) == -1) {
    return -1;
  }

  enabled = muted;
  return 0;
}

int32_t AudioDeviceLinuxPulse::MicrophoneMuteIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  bool isAvailable(false);
  bool wasInitialized = _mixerManager.MicrophoneIsInitialized();

  // Make an attempt to open up the
  // input mixer corresponding to the currently selected input device.
  //
  if (!wasInitialized && InitMicrophone() == -1) {
    // If we end up here it means that the selected microphone has no
    // volume control, hence it is safe to state that there is no
    // boost control already at this stage.
    available = false;
    return 0;
  }

  // Check if the selected microphone has a mute control
  //
  _mixerManager.MicrophoneMuteIsAvailable(isAvailable);
  available = isAvailable;

  // Close the initialized input mixer
  //
  if (!wasInitialized) {
    _mixerManager.CloseMicrophone();
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::SetMicrophoneMute(bool enable) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_mixerManager.SetMicrophoneMute(enable));
}

int32_t AudioDeviceLinuxPulse::MicrophoneMute(bool& enabled) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  bool muted(0);
  if (_mixerManager.MicrophoneMute(muted) == -1) {
    return -1;
  }

  enabled = muted;
  return 0;
}

int32_t AudioDeviceLinuxPulse::StereoRecordingIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_recChannels == 2 && _recording) {
    available = true;
    return 0;
  }

  available = false;
  bool wasInitialized = _mixerManager.MicrophoneIsInitialized();
  int error = 0;

  if (!wasInitialized && InitMicrophone() == -1) {
    // Cannot open the specified device
    available = false;
    return 0;
  }

  // Check if the selected microphone can record stereo.
  bool isAvailable(false);
  error = _mixerManager.StereoRecordingIsAvailable(isAvailable);
  if (!error)
    available = isAvailable;

  // Close the initialized input mixer
  if (!wasInitialized) {
    _mixerManager.CloseMicrophone();
  }

  return error;
}

int32_t AudioDeviceLinuxPulse::SetStereoRecording(bool enable) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (enable)
    _recChannels = 2;
  else
    _recChannels = 1;

  return 0;
}

int32_t AudioDeviceLinuxPulse::StereoRecording(bool& enabled) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_recChannels == 2)
    enabled = true;
  else
    enabled = false;

  return 0;
}

int32_t AudioDeviceLinuxPulse::StereoPlayoutIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_playChannels == 2 && _playing) {
    available = true;
    return 0;
  }

  available = false;
  bool wasInitialized = _mixerManager.SpeakerIsInitialized();
  int error = 0;

  if (!wasInitialized && InitSpeaker() == -1) {
    // Cannot open the specified device.
    return -1;
  }

  // Check if the selected speaker can play stereo.
  bool isAvailable(false);
  error = _mixerManager.StereoPlayoutIsAvailable(isAvailable);
  if (!error)
    available = isAvailable;

  // Close the initialized input mixer
  if (!wasInitialized) {
    _mixerManager.CloseSpeaker();
  }

  return error;
}

int32_t AudioDeviceLinuxPulse::SetStereoPlayout(bool enable) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (enable)
    _playChannels = 2;
  else
    _playChannels = 1;

  return 0;
}

int32_t AudioDeviceLinuxPulse::StereoPlayout(bool& enabled) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_playChannels == 2)
    enabled = true;
  else
    enabled = false;

  return 0;
}

int32_t AudioDeviceLinuxPulse::SetAGC(bool enable) {
  rtc::CritScope lock(&_critSect);
  _AGC = enable;

  return 0;
}

bool AudioDeviceLinuxPulse::AGC() const {
  rtc::CritScope lock(&_critSect);
  return _AGC;
}

int32_t AudioDeviceLinuxPulse::MicrophoneVolumeIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  bool wasInitialized = _mixerManager.MicrophoneIsInitialized();

  // Make an attempt to open up the
  // input mixer corresponding to the currently selected output device.
  if (!wasInitialized && InitMicrophone() == -1) {
    // If we end up here it means that the selected microphone has no
    // volume control.
    available = false;
    return 0;
  }

  // Given that InitMicrophone was successful, we know that a volume control
  // exists.
  available = true;

  // Close the initialized input mixer
  if (!wasInitialized) {
    _mixerManager.CloseMicrophone();
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::SetMicrophoneVolume(uint32_t volume) {
  return (_mixerManager.SetMicrophoneVolume(volume));
}

int32_t AudioDeviceLinuxPulse::MicrophoneVolume(uint32_t& volume) const {
  uint32_t level(0);

  if (_mixerManager.MicrophoneVolume(level) == -1) {
    LOG(LS_WARNING) << "failed to retrieve current microphone level";
    return -1;
  }

  volume = level;

  return 0;
}

int32_t AudioDeviceLinuxPulse::MaxMicrophoneVolume(uint32_t& maxVolume) const {
  uint32_t maxVol(0);

  if (_mixerManager.MaxMicrophoneVolume(maxVol) == -1) {
    return -1;
  }

  maxVolume = maxVol;

  return 0;
}

int32_t AudioDeviceLinuxPulse::MinMicrophoneVolume(uint32_t& minVolume) const {
  uint32_t minVol(0);

  if (_mixerManager.MinMicrophoneVolume(minVol) == -1) {
    return -1;
  }

  minVolume = minVol;

  return 0;
}

int16_t AudioDeviceLinuxPulse::PlayoutDevices() {
  PaLock();

  pa_operation* paOperation = NULL;
  _numPlayDevices = 1;  // init to 1 to account for "default"

  // get the whole list of devices and update _numPlayDevices
  paOperation =
      LATE(pa_context_get_sink_info_list)(_paContext, PaSinkInfoCallback, this);

  WaitForOperationCompletion(paOperation);

  PaUnLock();

  return _numPlayDevices;
}

int32_t AudioDeviceLinuxPulse::SetPlayoutDevice(uint16_t index) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_playIsInitialized) {
    return -1;
  }

  const uint16_t nDevices = PlayoutDevices();

  LOG(LS_VERBOSE) << "number of availiable output devices is " << nDevices;

  if (index > (nDevices - 1)) {
    LOG(LS_ERROR) << "device index is out of range [0," << (nDevices - 1)
                  << "]";
    return -1;
  }

  _outputDeviceIndex = index;
  _outputDeviceIsSpecified = true;

  return 0;
}

int32_t AudioDeviceLinuxPulse::SetPlayoutDevice(
    AudioDeviceModule::WindowsDeviceType /*device*/) {
  LOG(LS_ERROR) << "WindowsDeviceType not supported";
  return -1;
}

int32_t AudioDeviceLinuxPulse::PlayoutDeviceName(
    uint16_t index,
    char name[kAdmMaxDeviceNameSize],
    char guid[kAdmMaxGuidSize]) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  const uint16_t nDevices = PlayoutDevices();

  if ((index > (nDevices - 1)) || (name == NULL)) {
    return -1;
  }

  memset(name, 0, kAdmMaxDeviceNameSize);

  if (guid != NULL) {
    memset(guid, 0, kAdmMaxGuidSize);
  }

  // Check if default device
  if (index == 0) {
    uint16_t deviceIndex = 0;
    return GetDefaultDeviceInfo(false, name, deviceIndex);
  }

  // Tell the callback that we want
  // The name for this device
  _playDisplayDeviceName = name;
  _deviceIndex = index;

  // get playout devices
  PlayoutDevices();

  // clear device name and index
  _playDisplayDeviceName = NULL;
  _deviceIndex = -1;

  return 0;
}

int32_t AudioDeviceLinuxPulse::RecordingDeviceName(
    uint16_t index,
    char name[kAdmMaxDeviceNameSize],
    char guid[kAdmMaxGuidSize]) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  const uint16_t nDevices(RecordingDevices());

  if ((index > (nDevices - 1)) || (name == NULL)) {
    return -1;
  }

  memset(name, 0, kAdmMaxDeviceNameSize);

  if (guid != NULL) {
    memset(guid, 0, kAdmMaxGuidSize);
  }

  // Check if default device
  if (index == 0) {
    uint16_t deviceIndex = 0;
    return GetDefaultDeviceInfo(true, name, deviceIndex);
  }

  // Tell the callback that we want
  // the name for this device
  _recDisplayDeviceName = name;
  _deviceIndex = index;

  // Get recording devices
  RecordingDevices();

  // Clear device name and index
  _recDisplayDeviceName = NULL;
  _deviceIndex = -1;

  return 0;
}

int16_t AudioDeviceLinuxPulse::RecordingDevices() {
  PaLock();

  pa_operation* paOperation = NULL;
  _numRecDevices = 1;  // Init to 1 to account for "default"

  // Get the whole list of devices and update _numRecDevices
  paOperation = LATE(pa_context_get_source_info_list)(
      _paContext, PaSourceInfoCallback, this);

  WaitForOperationCompletion(paOperation);

  PaUnLock();

  return _numRecDevices;
}

int32_t AudioDeviceLinuxPulse::SetRecordingDevice(uint16_t index) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_recIsInitialized) {
    return -1;
  }

  const uint16_t nDevices(RecordingDevices());

  LOG(LS_VERBOSE) << "number of availiable input devices is " << nDevices;

  if (index > (nDevices - 1)) {
    LOG(LS_ERROR) << "device index is out of range [0," << (nDevices - 1)
                  << "]";
    return -1;
  }

  _inputDeviceIndex = index;
  _inputDeviceIsSpecified = true;

  return 0;
}

int32_t AudioDeviceLinuxPulse::SetRecordingDevice(
    AudioDeviceModule::WindowsDeviceType /*device*/) {
  LOG(LS_ERROR) << "WindowsDeviceType not supported";
  return -1;
}

int32_t AudioDeviceLinuxPulse::PlayoutIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  available = false;

  // Try to initialize the playout side
  int32_t res = InitPlayout();

  // Cancel effect of initialization
  StopPlayout();

  if (res != -1) {
    available = true;
  }

  return res;
}

int32_t AudioDeviceLinuxPulse::RecordingIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  available = false;

  // Try to initialize the playout side
  int32_t res = InitRecording();

  // Cancel effect of initialization
  StopRecording();

  if (res != -1) {
    available = true;
  }

  return res;
}

int32_t AudioDeviceLinuxPulse::InitPlayout() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());

  if (_playing) {
    return -1;
  }

  if (!_outputDeviceIsSpecified) {
    return -1;
  }

  if (_playIsInitialized) {
    return 0;
  }

  // Initialize the speaker (devices might have been added or removed)
  if (InitSpeaker() == -1) {
    LOG(LS_WARNING) << "InitSpeaker() failed";
  }

  // Set the play sample specification
  pa_sample_spec playSampleSpec;
  playSampleSpec.channels = _playChannels;
  playSampleSpec.format = PA_SAMPLE_S16LE;
  playSampleSpec.rate = sample_rate_hz_;

  // Create a new play stream
  _playStream =
      LATE(pa_stream_new)(_paContext, "playStream", &playSampleSpec, NULL);

  if (!_playStream) {
    LOG(LS_ERROR) << "failed to create play stream, err="
                  << LATE(pa_context_errno)(_paContext);
    return -1;
  }

  // Provide the playStream to the mixer
  _mixerManager.SetPlayStream(_playStream);

  if (_ptrAudioBuffer) {
    // Update audio buffer with the selected parameters
    _ptrAudioBuffer->SetPlayoutSampleRate(sample_rate_hz_);
    _ptrAudioBuffer->SetPlayoutChannels((uint8_t)_playChannels);
  }

  LOG(LS_VERBOSE) << "stream state " << LATE(pa_stream_get_state)(_playStream);

  // Set stream flags
  _playStreamFlags = (pa_stream_flags_t)(PA_STREAM_AUTO_TIMING_UPDATE |
                                         PA_STREAM_INTERPOLATE_TIMING);

  if (_configuredLatencyPlay != WEBRTC_PA_NO_LATENCY_REQUIREMENTS) {
    // If configuring a specific latency then we want to specify
    // PA_STREAM_ADJUST_LATENCY to make the server adjust parameters
    // automatically to reach that target latency. However, that flag
    // doesn't exist in Ubuntu 8.04 and many people still use that,
    // so we have to check the protocol version of libpulse.
    if (LATE(pa_context_get_protocol_version)(_paContext) >=
        WEBRTC_PA_ADJUST_LATENCY_PROTOCOL_VERSION) {
      _playStreamFlags |= PA_STREAM_ADJUST_LATENCY;
    }

    const pa_sample_spec* spec = LATE(pa_stream_get_sample_spec)(_playStream);
    if (!spec) {
      LOG(LS_ERROR) << "pa_stream_get_sample_spec()";
      return -1;
    }

    size_t bytesPerSec = LATE(pa_bytes_per_second)(spec);
    uint32_t latency = bytesPerSec * WEBRTC_PA_PLAYBACK_LATENCY_MINIMUM_MSECS /
                       WEBRTC_PA_MSECS_PER_SEC;

    // Set the play buffer attributes
    _playBufferAttr.maxlength = latency;  // num bytes stored in the buffer
    _playBufferAttr.tlength = latency;    // target fill level of play buffer
    // minimum free num bytes before server request more data
    _playBufferAttr.minreq = latency / WEBRTC_PA_PLAYBACK_REQUEST_FACTOR;
    // prebuffer tlength before starting playout
    _playBufferAttr.prebuf = _playBufferAttr.tlength - _playBufferAttr.minreq;

    _configuredLatencyPlay = latency;
  }

  // num samples in bytes * num channels
  _playbackBufferSize = sample_rate_hz_ / 100 * 2 * _playChannels;
  _playbackBufferUnused = _playbackBufferSize;
  _playBuffer = new int8_t[_playbackBufferSize];

  // Enable underflow callback
  LATE(pa_stream_set_underflow_callback)
  (_playStream, PaStreamUnderflowCallback, this);

  // Set the state callback function for the stream
  LATE(pa_stream_set_state_callback)(_playStream, PaStreamStateCallback, this);

  // Mark playout side as initialized
  _playIsInitialized = true;
  _sndCardPlayDelay = 0;
  _sndCardRecDelay = 0;

  return 0;
}

int32_t AudioDeviceLinuxPulse::InitRecording() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());

  if (_recording) {
    return -1;
  }

  if (!_inputDeviceIsSpecified) {
    return -1;
  }

  if (_recIsInitialized) {
    return 0;
  }

  // Initialize the microphone (devices might have been added or removed)
  if (InitMicrophone() == -1) {
    LOG(LS_WARNING) << "InitMicrophone() failed";
  }

  // Set the rec sample specification
  pa_sample_spec recSampleSpec;
  recSampleSpec.channels = _recChannels;
  recSampleSpec.format = PA_SAMPLE_S16LE;
  recSampleSpec.rate = sample_rate_hz_;

  // Create a new rec stream
  _recStream =
      LATE(pa_stream_new)(_paContext, "recStream", &recSampleSpec, NULL);
  if (!_recStream) {
    LOG(LS_ERROR) << "failed to create rec stream, err="
                  << LATE(pa_context_errno)(_paContext);
    return -1;
  }

  // Provide the recStream to the mixer
  _mixerManager.SetRecStream(_recStream);

  if (_ptrAudioBuffer) {
    // Update audio buffer with the selected parameters
    _ptrAudioBuffer->SetRecordingSampleRate(sample_rate_hz_);
    _ptrAudioBuffer->SetRecordingChannels((uint8_t)_recChannels);
  }

  if (_configuredLatencyRec != WEBRTC_PA_NO_LATENCY_REQUIREMENTS) {
    _recStreamFlags = (pa_stream_flags_t)(PA_STREAM_AUTO_TIMING_UPDATE |
                                          PA_STREAM_INTERPOLATE_TIMING);

    // If configuring a specific latency then we want to specify
    // PA_STREAM_ADJUST_LATENCY to make the server adjust parameters
    // automatically to reach that target latency. However, that flag
    // doesn't exist in Ubuntu 8.04 and many people still use that,
    //  so we have to check the protocol version of libpulse.
    if (LATE(pa_context_get_protocol_version)(_paContext) >=
        WEBRTC_PA_ADJUST_LATENCY_PROTOCOL_VERSION) {
      _recStreamFlags |= PA_STREAM_ADJUST_LATENCY;
    }

    const pa_sample_spec* spec = LATE(pa_stream_get_sample_spec)(_recStream);
    if (!spec) {
      LOG(LS_ERROR) << "pa_stream_get_sample_spec(rec)";
      return -1;
    }

    size_t bytesPerSec = LATE(pa_bytes_per_second)(spec);
    uint32_t latency = bytesPerSec * WEBRTC_PA_LOW_CAPTURE_LATENCY_MSECS /
                       WEBRTC_PA_MSECS_PER_SEC;

    // Set the rec buffer attributes
    // Note: fragsize specifies a maximum transfer size, not a minimum, so
    // it is not possible to force a high latency setting, only a low one.
    _recBufferAttr.fragsize = latency;  // size of fragment
    _recBufferAttr.maxlength =
        latency + bytesPerSec * WEBRTC_PA_CAPTURE_BUFFER_EXTRA_MSECS /
                      WEBRTC_PA_MSECS_PER_SEC;

    _configuredLatencyRec = latency;
  }

  _recordBufferSize = sample_rate_hz_ / 100 * 2 * _recChannels;
  _recordBufferUsed = 0;
  _recBuffer = new int8_t[_recordBufferSize];

  // Enable overflow callback
  LATE(pa_stream_set_overflow_callback)
  (_recStream, PaStreamOverflowCallback, this);

  // Set the state callback function for the stream
  LATE(pa_stream_set_state_callback)(_recStream, PaStreamStateCallback, this);

  // Mark recording side as initialized
  _recIsInitialized = true;

  return 0;
}

int32_t AudioDeviceLinuxPulse::StartRecording() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (!_recIsInitialized) {
    return -1;
  }

  if (_recording) {
    return 0;
  }

  // Set state to ensure that the recording starts from the audio thread.
  _startRec = true;

  // The audio thread will signal when recording has started.
  _timeEventRec.Set();
  if (kEventTimeout == _recStartEvent.Wait(10000)) {
    {
      rtc::CritScope lock(&_critSect);
      _startRec = false;
    }
    StopRecording();
    LOG(LS_ERROR) << "failed to activate recording";
    return -1;
  }

  {
    rtc::CritScope lock(&_critSect);
    if (_recording) {
      // The recording state is set by the audio thread after recording
      // has started.
    } else {
      LOG(LS_ERROR) << "failed to activate recording";
      return -1;
    }
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::StopRecording() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  rtc::CritScope lock(&_critSect);

  if (!_recIsInitialized) {
    return 0;
  }

  if (_recStream == NULL) {
    return -1;
  }

  _recIsInitialized = false;
  _recording = false;

  LOG(LS_VERBOSE) << "stopping recording";

  // Stop Recording
  PaLock();

  DisableReadCallback();
  LATE(pa_stream_set_overflow_callback)(_recStream, NULL, NULL);

  // Unset this here so that we don't get a TERMINATED callback
  LATE(pa_stream_set_state_callback)(_recStream, NULL, NULL);

  if (LATE(pa_stream_get_state)(_recStream) != PA_STREAM_UNCONNECTED) {
    // Disconnect the stream
    if (LATE(pa_stream_disconnect)(_recStream) != PA_OK) {
      LOG(LS_ERROR) << "failed to disconnect rec stream, err="
                    << LATE(pa_context_errno)(_paContext);
      PaUnLock();
      return -1;
    }

    LOG(LS_VERBOSE) << "disconnected recording";
  }

  LATE(pa_stream_unref)(_recStream);
  _recStream = NULL;

  PaUnLock();

  // Provide the recStream to the mixer
  _mixerManager.SetRecStream(_recStream);

  if (_recBuffer) {
    delete[] _recBuffer;
    _recBuffer = NULL;
  }

  return 0;
}

bool AudioDeviceLinuxPulse::RecordingIsInitialized() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_recIsInitialized);
}

bool AudioDeviceLinuxPulse::Recording() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_recording);
}

bool AudioDeviceLinuxPulse::PlayoutIsInitialized() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_playIsInitialized);
}

int32_t AudioDeviceLinuxPulse::StartPlayout() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());

  if (!_playIsInitialized) {
    return -1;
  }

  if (_playing) {
    return 0;
  }

  // Set state to ensure that playout starts from the audio thread.
  {
    rtc::CritScope lock(&_critSect);
    _startPlay = true;
  }

  // Both |_startPlay| and |_playing| needs protction since they are also
  // accessed on the playout thread.

  // The audio thread will signal when playout has started.
  _timeEventPlay.Set();
  if (kEventTimeout == _playStartEvent.Wait(10000)) {
    {
      rtc::CritScope lock(&_critSect);
      _startPlay = false;
    }
    StopPlayout();
    LOG(LS_ERROR) << "failed to activate playout";
    return -1;
  }

  {
    rtc::CritScope lock(&_critSect);
    if (_playing) {
      // The playing state is set by the audio thread after playout
      // has started.
    } else {
      LOG(LS_ERROR) << "failed to activate playing";
      return -1;
    }
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::StopPlayout() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  rtc::CritScope lock(&_critSect);

  if (!_playIsInitialized) {
    return 0;
  }

  if (_playStream == NULL) {
    return -1;
  }

  _playIsInitialized = false;
  _playing = false;
  _sndCardPlayDelay = 0;
  _sndCardRecDelay = 0;

  LOG(LS_VERBOSE) << "stopping playback";

  // Stop Playout
  PaLock();

  DisableWriteCallback();
  LATE(pa_stream_set_underflow_callback)(_playStream, NULL, NULL);

  // Unset this here so that we don't get a TERMINATED callback
  LATE(pa_stream_set_state_callback)(_playStream, NULL, NULL);

  if (LATE(pa_stream_get_state)(_playStream) != PA_STREAM_UNCONNECTED) {
    // Disconnect the stream
    if (LATE(pa_stream_disconnect)(_playStream) != PA_OK) {
      LOG(LS_ERROR) << "failed to disconnect play stream, err="
                    << LATE(pa_context_errno)(_paContext);
      PaUnLock();
      return -1;
    }

    LOG(LS_VERBOSE) << "disconnected playback";
  }

  LATE(pa_stream_unref)(_playStream);
  _playStream = NULL;

  PaUnLock();

  // Provide the playStream to the mixer
  _mixerManager.SetPlayStream(_playStream);

  if (_playBuffer) {
    delete[] _playBuffer;
    _playBuffer = NULL;
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::PlayoutDelay(uint16_t& delayMS) const {
  rtc::CritScope lock(&_critSect);
  delayMS = (uint16_t)_sndCardPlayDelay;
  return 0;
}

int32_t AudioDeviceLinuxPulse::RecordingDelay(uint16_t& delayMS) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  delayMS = (uint16_t)_sndCardRecDelay;
  return 0;
}

bool AudioDeviceLinuxPulse::Playing() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  return (_playing);
}

bool AudioDeviceLinuxPulse::PlayoutWarning() const {
  rtc::CritScope lock(&_critSect);
  return (_playWarning > 0);
}

bool AudioDeviceLinuxPulse::PlayoutError() const {
  rtc::CritScope lock(&_critSect);
  return (_playError > 0);
}

bool AudioDeviceLinuxPulse::RecordingWarning() const {
  rtc::CritScope lock(&_critSect);
  return (_recWarning > 0);
}

bool AudioDeviceLinuxPulse::RecordingError() const {
  rtc::CritScope lock(&_critSect);
  return (_recError > 0);
}

void AudioDeviceLinuxPulse::ClearPlayoutWarning() {
  rtc::CritScope lock(&_critSect);
  _playWarning = 0;
}

void AudioDeviceLinuxPulse::ClearPlayoutError() {
  rtc::CritScope lock(&_critSect);
  _playError = 0;
}

void AudioDeviceLinuxPulse::ClearRecordingWarning() {
  rtc::CritScope lock(&_critSect);
  _recWarning = 0;
}

void AudioDeviceLinuxPulse::ClearRecordingError() {
  rtc::CritScope lock(&_critSect);
  _recError = 0;
}

// ============================================================================
//                                 Private Methods
// ============================================================================

void AudioDeviceLinuxPulse::PaContextStateCallback(pa_context* c, void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)->PaContextStateCallbackHandler(c);
}

// ----------------------------------------------------------------------------
//  PaSinkInfoCallback
// ----------------------------------------------------------------------------

void AudioDeviceLinuxPulse::PaSinkInfoCallback(pa_context* /*c*/,
                                               const pa_sink_info* i,
                                               int eol,
                                               void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)->PaSinkInfoCallbackHandler(i, eol);
}

void AudioDeviceLinuxPulse::PaSourceInfoCallback(pa_context* /*c*/,
                                                 const pa_source_info* i,
                                                 int eol,
                                                 void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)->PaSourceInfoCallbackHandler(i,
                                                                          eol);
}

void AudioDeviceLinuxPulse::PaServerInfoCallback(pa_context* /*c*/,
                                                 const pa_server_info* i,
                                                 void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)->PaServerInfoCallbackHandler(i);
}

void AudioDeviceLinuxPulse::PaStreamStateCallback(pa_stream* p, void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)->PaStreamStateCallbackHandler(p);
}

void AudioDeviceLinuxPulse::PaContextStateCallbackHandler(pa_context* c) {
  LOG(LS_VERBOSE) << "context state cb";

  pa_context_state_t state = LATE(pa_context_get_state)(c);
  switch (state) {
    case PA_CONTEXT_UNCONNECTED:
      LOG(LS_VERBOSE) << "unconnected";
      break;
    case PA_CONTEXT_CONNECTING:
    case PA_CONTEXT_AUTHORIZING:
    case PA_CONTEXT_SETTING_NAME:
      LOG(LS_VERBOSE) << "no state";
      break;
    case PA_CONTEXT_FAILED:
    case PA_CONTEXT_TERMINATED:
      LOG(LS_VERBOSE) << "failed";
      _paStateChanged = true;
      LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
      break;
    case PA_CONTEXT_READY:
      LOG(LS_VERBOSE) << "ready";
      _paStateChanged = true;
      LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
      break;
  }
}

void AudioDeviceLinuxPulse::PaSinkInfoCallbackHandler(const pa_sink_info* i,
                                                      int eol) {
  if (eol) {
    // Signal that we are done
    LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
    return;
  }

  if (_numPlayDevices == _deviceIndex) {
    // Convert the device index to the one of the sink
    _paDeviceIndex = i->index;

    if (_playDeviceName) {
      // Copy the sink name
      strncpy(_playDeviceName, i->name, kAdmMaxDeviceNameSize);
      _playDeviceName[kAdmMaxDeviceNameSize - 1] = '\0';
    }
    if (_playDisplayDeviceName) {
      // Copy the sink display name
      strncpy(_playDisplayDeviceName, i->description, kAdmMaxDeviceNameSize);
      _playDisplayDeviceName[kAdmMaxDeviceNameSize - 1] = '\0';
    }
  }

  _numPlayDevices++;
}

void AudioDeviceLinuxPulse::PaSourceInfoCallbackHandler(const pa_source_info* i,
                                                        int eol) {
  if (eol) {
    // Signal that we are done
    LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
    return;
  }

  // We don't want to list output devices
  if (i->monitor_of_sink == PA_INVALID_INDEX) {
    if (_numRecDevices == _deviceIndex) {
      // Convert the device index to the one of the source
      _paDeviceIndex = i->index;

      if (_recDeviceName) {
        // copy the source name
        strncpy(_recDeviceName, i->name, kAdmMaxDeviceNameSize);
        _recDeviceName[kAdmMaxDeviceNameSize - 1] = '\0';
      }
      if (_recDisplayDeviceName) {
        // Copy the source display name
        strncpy(_recDisplayDeviceName, i->description, kAdmMaxDeviceNameSize);
        _recDisplayDeviceName[kAdmMaxDeviceNameSize - 1] = '\0';
      }
    }

    _numRecDevices++;
  }
}

void AudioDeviceLinuxPulse::PaServerInfoCallbackHandler(
    const pa_server_info* i) {
  // Use PA native sampling rate
  sample_rate_hz_ = i->sample_spec.rate;

  // Copy the PA server version
  strncpy(_paServerVersion, i->server_version, 31);
  _paServerVersion[31] = '\0';

  if (_recDisplayDeviceName) {
    // Copy the source name
    strncpy(_recDisplayDeviceName, i->default_source_name,
            kAdmMaxDeviceNameSize);
    _recDisplayDeviceName[kAdmMaxDeviceNameSize - 1] = '\0';
  }

  if (_playDisplayDeviceName) {
    // Copy the sink name
    strncpy(_playDisplayDeviceName, i->default_sink_name,
            kAdmMaxDeviceNameSize);
    _playDisplayDeviceName[kAdmMaxDeviceNameSize - 1] = '\0';
  }

  LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
}

void AudioDeviceLinuxPulse::PaStreamStateCallbackHandler(pa_stream* p) {
  LOG(LS_VERBOSE) << "stream state cb";

  pa_stream_state_t state = LATE(pa_stream_get_state)(p);
  switch (state) {
    case PA_STREAM_UNCONNECTED:
      LOG(LS_VERBOSE) << "unconnected";
      break;
    case PA_STREAM_CREATING:
      LOG(LS_VERBOSE) << "creating";
      break;
    case PA_STREAM_FAILED:
    case PA_STREAM_TERMINATED:
      LOG(LS_VERBOSE) << "failed";
      break;
    case PA_STREAM_READY:
      LOG(LS_VERBOSE) << "ready";
      break;
  }

  LATE(pa_threaded_mainloop_signal)(_paMainloop, 0);
}

int32_t AudioDeviceLinuxPulse::CheckPulseAudioVersion() {
  PaLock();

  pa_operation* paOperation = NULL;

  // get the server info and update deviceName
  paOperation =
      LATE(pa_context_get_server_info)(_paContext, PaServerInfoCallback, this);

  WaitForOperationCompletion(paOperation);

  PaUnLock();

  LOG(LS_VERBOSE) << "checking PulseAudio version: " << _paServerVersion;

  return 0;
}

int32_t AudioDeviceLinuxPulse::InitSamplingFrequency() {
  PaLock();

  pa_operation* paOperation = NULL;

  // Get the server info and update sample_rate_hz_
  paOperation =
      LATE(pa_context_get_server_info)(_paContext, PaServerInfoCallback, this);

  WaitForOperationCompletion(paOperation);

  PaUnLock();

  return 0;
}

int32_t AudioDeviceLinuxPulse::GetDefaultDeviceInfo(bool recDevice,
                                                    char* name,
                                                    uint16_t& index) {
  char tmpName[kAdmMaxDeviceNameSize] = {0};
  // subtract length of "default: "
  uint16_t nameLen = kAdmMaxDeviceNameSize - 9;
  char* pName = NULL;

  if (name) {
    // Add "default: "
    strcpy(name, "default: ");
    pName = &name[9];
  }

  // Tell the callback that we want
  // the name for this device
  if (recDevice) {
    _recDisplayDeviceName = tmpName;
  } else {
    _playDisplayDeviceName = tmpName;
  }

  // Set members
  _paDeviceIndex = -1;
  _deviceIndex = 0;
  _numPlayDevices = 0;
  _numRecDevices = 0;

  PaLock();

  pa_operation* paOperation = NULL;

  // Get the server info and update deviceName
  paOperation =
      LATE(pa_context_get_server_info)(_paContext, PaServerInfoCallback, this);

  WaitForOperationCompletion(paOperation);

  // Get the device index
  if (recDevice) {
    paOperation = LATE(pa_context_get_source_info_by_name)(
        _paContext, (char*)tmpName, PaSourceInfoCallback, this);
  } else {
    paOperation = LATE(pa_context_get_sink_info_by_name)(
        _paContext, (char*)tmpName, PaSinkInfoCallback, this);
  }

  WaitForOperationCompletion(paOperation);

  PaUnLock();

  // Set the index
  index = _paDeviceIndex;

  if (name) {
    // Copy to name string
    strncpy(pName, tmpName, nameLen);
  }

  // Clear members
  _playDisplayDeviceName = NULL;
  _recDisplayDeviceName = NULL;
  _paDeviceIndex = -1;
  _deviceIndex = -1;
  _numPlayDevices = 0;
  _numRecDevices = 0;

  return 0;
}

int32_t AudioDeviceLinuxPulse::InitPulseAudio() {
  int retVal = 0;

  // Load libpulse
  if (!PaSymbolTable.Load()) {
    // Most likely the Pulse library and sound server are not installed on
    // this system
    LOG(LS_ERROR) << "failed to load symbol table";
    return -1;
  }

  // Create a mainloop API and connection to the default server
  // the mainloop is the internal asynchronous API event loop
  if (_paMainloop) {
    LOG(LS_ERROR) << "PA mainloop has already existed";
    return -1;
  }
  _paMainloop = LATE(pa_threaded_mainloop_new)();
  if (!_paMainloop) {
    LOG(LS_ERROR) << "could not create mainloop";
    return -1;
  }

  // Start the threaded main loop
  retVal = LATE(pa_threaded_mainloop_start)(_paMainloop);
  if (retVal != PA_OK) {
    LOG(LS_ERROR) << "failed to start main loop, error=" << retVal;
    return -1;
  }

  LOG(LS_VERBOSE) << "mainloop running!";

  PaLock();

  _paMainloopApi = LATE(pa_threaded_mainloop_get_api)(_paMainloop);
  if (!_paMainloopApi) {
    LOG(LS_ERROR) << "could not create mainloop API";
    PaUnLock();
    return -1;
  }

  // Create a new PulseAudio context
  if (_paContext) {
    LOG(LS_ERROR) << "PA context has already existed";
    PaUnLock();
    return -1;
  }
  _paContext = LATE(pa_context_new)(_paMainloopApi, "WEBRTC VoiceEngine");

  if (!_paContext) {
    LOG(LS_ERROR) << "could not create context";
    PaUnLock();
    return -1;
  }

  // Set state callback function
  LATE(pa_context_set_state_callback)(_paContext, PaContextStateCallback, this);

  // Connect the context to a server (default)
  _paStateChanged = false;
  retVal =
      LATE(pa_context_connect)(_paContext, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL);

  if (retVal != PA_OK) {
    LOG(LS_ERROR) << "failed to connect context, error=" << retVal;
    PaUnLock();
    return -1;
  }

  // Wait for state change
  while (!_paStateChanged) {
    LATE(pa_threaded_mainloop_wait)(_paMainloop);
  }

  // Now check to see what final state we reached.
  pa_context_state_t state = LATE(pa_context_get_state)(_paContext);

  if (state != PA_CONTEXT_READY) {
    if (state == PA_CONTEXT_FAILED) {
      LOG(LS_ERROR) << "failed to connect to PulseAudio sound server";
    } else if (state == PA_CONTEXT_TERMINATED) {
      LOG(LS_ERROR) << "PulseAudio connection terminated early";
    } else {
      // Shouldn't happen, because we only signal on one of those three
      // states
      LOG(LS_ERROR) << "unknown problem connecting to PulseAudio";
    }
    PaUnLock();
    return -1;
  }

  PaUnLock();

  // Give the objects to the mixer manager
  _mixerManager.SetPulseAudioObjects(_paMainloop, _paContext);

  // Check the version
  if (CheckPulseAudioVersion() < 0) {
    LOG(LS_ERROR) << "PulseAudio version " << _paServerVersion
                  << " not supported";
    return -1;
  }

  // Initialize sampling frequency
  if (InitSamplingFrequency() < 0 || sample_rate_hz_ == 0) {
    LOG(LS_ERROR) << "failed to initialize sampling frequency, set to "
                  << sample_rate_hz_ << " Hz";
    return -1;
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::TerminatePulseAudio() {
  // Do nothing if the instance doesn't exist
  // likely PaSymbolTable.Load() fails
  if (!_paMainloop) {
    return 0;
  }

  PaLock();

  // Disconnect the context
  if (_paContext) {
    LATE(pa_context_disconnect)(_paContext);
  }

  // Unreference the context
  if (_paContext) {
    LATE(pa_context_unref)(_paContext);
  }

  PaUnLock();
  _paContext = NULL;

  // Stop the threaded main loop
  if (_paMainloop) {
    LATE(pa_threaded_mainloop_stop)(_paMainloop);
  }

  // Free the mainloop
  if (_paMainloop) {
    LATE(pa_threaded_mainloop_free)(_paMainloop);
  }

  _paMainloop = NULL;

  LOG(LS_VERBOSE) << "PulseAudio terminated";

  return 0;
}

void AudioDeviceLinuxPulse::PaLock() {
  LATE(pa_threaded_mainloop_lock)(_paMainloop);
}

void AudioDeviceLinuxPulse::PaUnLock() {
  LATE(pa_threaded_mainloop_unlock)(_paMainloop);
}

void AudioDeviceLinuxPulse::WaitForOperationCompletion(
    pa_operation* paOperation) const {
  if (!paOperation) {
    LOG(LS_ERROR) << "paOperation NULL in WaitForOperationCompletion";
    return;
  }

  while (LATE(pa_operation_get_state)(paOperation) == PA_OPERATION_RUNNING) {
    LATE(pa_threaded_mainloop_wait)(_paMainloop);
  }

  LATE(pa_operation_unref)(paOperation);
}

// ============================================================================
//                                  Thread Methods
// ============================================================================

void AudioDeviceLinuxPulse::EnableWriteCallback() {
  if (LATE(pa_stream_get_state)(_playStream) == PA_STREAM_READY) {
    // May already have available space. Must check.
    _tempBufferSpace = LATE(pa_stream_writable_size)(_playStream);
    if (_tempBufferSpace > 0) {
      // Yup, there is already space available, so if we register a
      // write callback then it will not receive any event. So dispatch
      // one ourself instead.
      _timeEventPlay.Set();
      return;
    }
  }

  LATE(pa_stream_set_write_callback)(_playStream, &PaStreamWriteCallback, this);
}

void AudioDeviceLinuxPulse::DisableWriteCallback() {
  LATE(pa_stream_set_write_callback)(_playStream, NULL, NULL);
}

void AudioDeviceLinuxPulse::PaStreamWriteCallback(pa_stream* /*unused*/,
                                                  size_t buffer_space,
                                                  void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)->PaStreamWriteCallbackHandler(
      buffer_space);
}

void AudioDeviceLinuxPulse::PaStreamWriteCallbackHandler(size_t bufferSpace) {
  _tempBufferSpace = bufferSpace;

  // Since we write the data asynchronously on a different thread, we have
  // to temporarily disable the write callback or else Pulse will call it
  // continuously until we write the data. We re-enable it below.
  DisableWriteCallback();
  _timeEventPlay.Set();
}

void AudioDeviceLinuxPulse::PaStreamUnderflowCallback(pa_stream* /*unused*/,
                                                      void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)
      ->PaStreamUnderflowCallbackHandler();
}

void AudioDeviceLinuxPulse::PaStreamUnderflowCallbackHandler() {
  LOG(LS_WARNING) << "Playout underflow";

  if (_configuredLatencyPlay == WEBRTC_PA_NO_LATENCY_REQUIREMENTS) {
    // We didn't configure a pa_buffer_attr before, so switching to
    // one now would be questionable.
    return;
  }

  // Otherwise reconfigure the stream with a higher target latency.

  const pa_sample_spec* spec = LATE(pa_stream_get_sample_spec)(_playStream);
  if (!spec) {
    LOG(LS_ERROR) << "pa_stream_get_sample_spec()";
    return;
  }

  size_t bytesPerSec = LATE(pa_bytes_per_second)(spec);
  uint32_t newLatency =
      _configuredLatencyPlay + bytesPerSec *
                                   WEBRTC_PA_PLAYBACK_LATENCY_INCREMENT_MSECS /
                                   WEBRTC_PA_MSECS_PER_SEC;

  // Set the play buffer attributes
  _playBufferAttr.maxlength = newLatency;
  _playBufferAttr.tlength = newLatency;
  _playBufferAttr.minreq = newLatency / WEBRTC_PA_PLAYBACK_REQUEST_FACTOR;
  _playBufferAttr.prebuf = _playBufferAttr.tlength - _playBufferAttr.minreq;

  pa_operation* op = LATE(pa_stream_set_buffer_attr)(
      _playStream, &_playBufferAttr, NULL, NULL);
  if (!op) {
    LOG(LS_ERROR) << "pa_stream_set_buffer_attr()";
    return;
  }

  // Don't need to wait for this to complete.
  LATE(pa_operation_unref)(op);

  // Save the new latency in case we underflow again.
  _configuredLatencyPlay = newLatency;
}

void AudioDeviceLinuxPulse::EnableReadCallback() {
  LATE(pa_stream_set_read_callback)(_recStream, &PaStreamReadCallback, this);
}

void AudioDeviceLinuxPulse::DisableReadCallback() {
  LATE(pa_stream_set_read_callback)(_recStream, NULL, NULL);
}

void AudioDeviceLinuxPulse::PaStreamReadCallback(pa_stream* /*unused1*/,
                                                 size_t /*unused2*/,
                                                 void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)->PaStreamReadCallbackHandler();
}

void AudioDeviceLinuxPulse::PaStreamReadCallbackHandler() {
  // We get the data pointer and size now in order to save one Lock/Unlock
  // in the worker thread.
  if (LATE(pa_stream_peek)(_recStream, &_tempSampleData,
                           &_tempSampleDataSize) != 0) {
    LOG(LS_ERROR) << "Can't read data!";
    return;
  }

  // Since we consume the data asynchronously on a different thread, we have
  // to temporarily disable the read callback or else Pulse will call it
  // continuously until we consume the data. We re-enable it below.
  DisableReadCallback();
  _timeEventRec.Set();
}

void AudioDeviceLinuxPulse::PaStreamOverflowCallback(pa_stream* /*unused*/,
                                                     void* pThis) {
  static_cast<AudioDeviceLinuxPulse*>(pThis)->PaStreamOverflowCallbackHandler();
}

void AudioDeviceLinuxPulse::PaStreamOverflowCallbackHandler() {
  LOG(LS_WARNING) << "Recording overflow";
}

int32_t AudioDeviceLinuxPulse::LatencyUsecs(pa_stream* stream) {
  if (!WEBRTC_PA_REPORT_LATENCY) {
    return 0;
  }

  if (!stream) {
    return 0;
  }

  pa_usec_t latency;
  int negative;
  if (LATE(pa_stream_get_latency)(stream, &latency, &negative) != 0) {
    LOG(LS_ERROR) << "Can't query latency";
    // We'd rather continue playout/capture with an incorrect delay than
    // stop it altogether, so return a valid value.
    return 0;
  }

  if (negative) {
    LOG(LS_VERBOSE) << "warning: pa_stream_get_latency reported negative delay";

    // The delay can be negative for monitoring streams if the captured
    // samples haven't been played yet. In such a case, "latency"
    // contains the magnitude, so we must negate it to get the real value.
    int32_t tmpLatency = (int32_t)-latency;
    if (tmpLatency < 0) {
      // Make sure that we don't use a negative delay.
      tmpLatency = 0;
    }

    return tmpLatency;
  } else {
    return (int32_t)latency;
  }
}

int32_t AudioDeviceLinuxPulse::ReadRecordedData(const void* bufferData,
                                                size_t bufferSize)
    RTC_EXCLUSIVE_LOCKS_REQUIRED(_critSect) {
  size_t size = bufferSize;
  uint32_t numRecSamples = _recordBufferSize / (2 * _recChannels);

  // Account for the peeked data and the used data.
  uint32_t recDelay =
      (uint32_t)((LatencyUsecs(_recStream) / 1000) +
                 10 * ((size + _recordBufferUsed) / _recordBufferSize));

  _sndCardRecDelay = recDelay;

  if (_playStream) {
    // Get the playout delay.
    _sndCardPlayDelay = (uint32_t)(LatencyUsecs(_playStream) / 1000);
  }

  if (_recordBufferUsed > 0) {
    // Have to copy to the buffer until it is full.
    size_t copy = _recordBufferSize - _recordBufferUsed;
    if (size < copy) {
      copy = size;
    }

    memcpy(&_recBuffer[_recordBufferUsed], bufferData, copy);
    _recordBufferUsed += copy;
    bufferData = static_cast<const char*>(bufferData) + copy;
    size -= copy;

    if (_recordBufferUsed != _recordBufferSize) {
      // Not enough data yet to pass to VoE.
      return 0;
    }

    // Provide data to VoiceEngine.
    if (ProcessRecordedData(_recBuffer, numRecSamples, recDelay) == -1) {
      // We have stopped recording.
      return -1;
    }

    _recordBufferUsed = 0;
  }

  // Now process full 10ms sample sets directly from the input.
  while (size >= _recordBufferSize) {
    // Provide data to VoiceEngine.
    if (ProcessRecordedData(static_cast<int8_t*>(const_cast<void*>(bufferData)),
                            numRecSamples, recDelay) == -1) {
      // We have stopped recording.
      return -1;
    }

    bufferData = static_cast<const char*>(bufferData) + _recordBufferSize;
    size -= _recordBufferSize;

    // We have consumed 10ms of data.
    recDelay -= 10;
  }

  // Now save any leftovers for later.
  if (size > 0) {
    memcpy(_recBuffer, bufferData, size);
    _recordBufferUsed = size;
  }

  return 0;
}

int32_t AudioDeviceLinuxPulse::ProcessRecordedData(int8_t* bufferData,
                                                   uint32_t bufferSizeInSamples,
                                                   uint32_t recDelay)
    RTC_EXCLUSIVE_LOCKS_REQUIRED(_critSect) {
  uint32_t currentMicLevel(0);
  uint32_t newMicLevel(0);

  _ptrAudioBuffer->SetRecordedBuffer(bufferData, bufferSizeInSamples);

  if (AGC()) {
    // Store current mic level in the audio buffer if AGC is enabled
    if (MicrophoneVolume(currentMicLevel) == 0) {
      // This call does not affect the actual microphone volume
      _ptrAudioBuffer->SetCurrentMicLevel(currentMicLevel);
    }
  }

  const uint32_t clockDrift(0);
  // TODO(andrew): this is a temporary hack, to avoid non-causal far- and
  // near-end signals at the AEC for PulseAudio. I think the system delay is
  // being correctly calculated here, but for legacy reasons we add +10 ms
  // to the value in the AEC. The real fix will be part of a larger
  // investigation into managing system delay in the AEC.
  if (recDelay > 10)
    recDelay -= 10;
  else
    recDelay = 0;
  _ptrAudioBuffer->SetVQEData(_sndCardPlayDelay, recDelay, clockDrift);
  _ptrAudioBuffer->SetTypingStatus(KeyPressed());
  // Deliver recorded samples at specified sample rate,
  // mic level etc. to the observer using callback.
  UnLock();
  _ptrAudioBuffer->DeliverRecordedData();
  Lock();

  // We have been unlocked - check the flag again.
  if (!_recording) {
    return -1;
  }

  if (AGC()) {
    newMicLevel = _ptrAudioBuffer->NewMicLevel();
    if (newMicLevel != 0) {
      // The VQE will only deliver non-zero microphone levels when a
      // change is needed.
      // Set this new mic level (received from the observer as return
      // value in the callback).
      LOG(LS_VERBOSE) << "AGC change of volume: old=" << currentMicLevel
                      << " => new=" << newMicLevel;
      if (SetMicrophoneVolume(newMicLevel) == -1) {
        LOG(LS_WARNING)
            << "the required modification of the microphone volume failed";
      }
    }
  }

  return 0;
}

bool AudioDeviceLinuxPulse::PlayThreadFunc(void* pThis) {
  return (static_cast<AudioDeviceLinuxPulse*>(pThis)->PlayThreadProcess());
}

bool AudioDeviceLinuxPulse::RecThreadFunc(void* pThis) {
  return (static_cast<AudioDeviceLinuxPulse*>(pThis)->RecThreadProcess());
}

bool AudioDeviceLinuxPulse::PlayThreadProcess() {
  switch (_timeEventPlay.Wait(1000)) {
    case kEventSignaled:
      break;
    case kEventError:
      LOG(LS_WARNING) << "EventWrapper::Wait() failed";
      return true;
    case kEventTimeout:
      return true;
  }

  rtc::CritScope lock(&_critSect);

  if (_startPlay) {
    LOG(LS_VERBOSE) << "_startPlay true, performing initial actions";

    _startPlay = false;
    _playDeviceName = NULL;

    // Set if not default device
    if (_outputDeviceIndex > 0) {
      // Get the playout device name
      _playDeviceName = new char[kAdmMaxDeviceNameSize];
      _deviceIndex = _outputDeviceIndex;
      PlayoutDevices();
    }

    // Start muted only supported on 0.9.11 and up
    if (LATE(pa_context_get_protocol_version)(_paContext) >=
        WEBRTC_PA_ADJUST_LATENCY_PROTOCOL_VERSION) {
      // Get the currently saved speaker mute status
      // and set the initial mute status accordingly
      bool enabled(false);
      _mixerManager.SpeakerMute(enabled);
      if (enabled) {
        _playStreamFlags |= PA_STREAM_START_MUTED;
      }
    }

    // Get the currently saved speaker volume
    uint32_t volume = 0;
    if (update_speaker_volume_at_startup_)
      _mixerManager.SpeakerVolume(volume);

    PaLock();

    // NULL gives PA the choice of startup volume.
    pa_cvolume* ptr_cvolume = NULL;
    if (update_speaker_volume_at_startup_) {
      pa_cvolume cVolumes;
      ptr_cvolume = &cVolumes;

      // Set the same volume for all channels
      const pa_sample_spec* spec = LATE(pa_stream_get_sample_spec)(_playStream);
      LATE(pa_cvolume_set)(&cVolumes, spec->channels, volume);
      update_speaker_volume_at_startup_ = false;
    }

    // Connect the stream to a sink
    if (LATE(pa_stream_connect_playback)(
            _playStream, _playDeviceName, &_playBufferAttr,
            (pa_stream_flags_t)_playStreamFlags, ptr_cvolume, NULL) != PA_OK) {
      LOG(LS_ERROR) << "failed to connect play stream, err="
                    << LATE(pa_context_errno)(_paContext);
    }

    LOG(LS_VERBOSE) << "play stream connected";

    // Wait for state change
    while (LATE(pa_stream_get_state)(_playStream) != PA_STREAM_READY) {
      LATE(pa_threaded_mainloop_wait)(_paMainloop);
    }

    LOG(LS_VERBOSE) << "play stream ready";

    // We can now handle write callbacks
    EnableWriteCallback();

    PaUnLock();

    // Clear device name
    if (_playDeviceName) {
      delete[] _playDeviceName;
      _playDeviceName = NULL;
    }

    _playing = true;
    _playStartEvent.Set();

    return true;
  }

  if (_playing) {
    if (!_recording) {
      // Update the playout delay
      _sndCardPlayDelay = (uint32_t)(LatencyUsecs(_playStream) / 1000);
    }

    if (_playbackBufferUnused < _playbackBufferSize) {
      size_t write = _playbackBufferSize - _playbackBufferUnused;
      if (_tempBufferSpace < write) {
        write = _tempBufferSpace;
      }

      PaLock();
      if (LATE(pa_stream_write)(
              _playStream, (void*)&_playBuffer[_playbackBufferUnused], write,
              NULL, (int64_t)0, PA_SEEK_RELATIVE) != PA_OK) {
        _writeErrors++;
        if (_writeErrors > 10) {
          if (_playError == 1) {
            LOG(LS_WARNING) << "pending playout error exists";
          }
          // Triggers callback from module process thread.
          _playError = 1;
          LOG(LS_ERROR) << "kPlayoutError message posted: _writeErrors="
                        << _writeErrors
                        << ", error=" << LATE(pa_context_errno)(_paContext);
          _writeErrors = 0;
        }
      }
      PaUnLock();

      _playbackBufferUnused += write;
      _tempBufferSpace -= write;
    }

    uint32_t numPlaySamples = _playbackBufferSize / (2 * _playChannels);
    // Might have been reduced to zero by the above.
    if (_tempBufferSpace > 0) {
      // Ask for new PCM data to be played out using the
      // AudioDeviceBuffer ensure that this callback is executed
      // without taking the audio-thread lock.
      UnLock();
      LOG(LS_VERBOSE) << "requesting data";
      uint32_t nSamples = _ptrAudioBuffer->RequestPlayoutData(numPlaySamples);
      Lock();

      // We have been unlocked - check the flag again.
      if (!_playing) {
        return true;
      }

      nSamples = _ptrAudioBuffer->GetPlayoutData(_playBuffer);
      if (nSamples != numPlaySamples) {
        LOG(LS_ERROR) << "invalid number of output samples(" << nSamples << ")";
      }

      size_t write = _playbackBufferSize;
      if (_tempBufferSpace < write) {
        write = _tempBufferSpace;
      }

      LOG(LS_VERBOSE) << "will write";
      PaLock();
      if (LATE(pa_stream_write)(_playStream, (void*)&_playBuffer[0], write,
                                NULL, (int64_t)0, PA_SEEK_RELATIVE) != PA_OK) {
        _writeErrors++;
        if (_writeErrors > 10) {
          if (_playError == 1) {
            LOG(LS_WARNING) << "pending playout error exists";
          }
          // Triggers callback from module process thread.
          _playError = 1;
          LOG(LS_ERROR) << "kPlayoutError message posted: _writeErrors="
                        << _writeErrors
                        << ", error=" << LATE(pa_context_errno)(_paContext);
          _writeErrors = 0;
        }
      }
      PaUnLock();

      _playbackBufferUnused = write;
    }

    _tempBufferSpace = 0;
    PaLock();
    EnableWriteCallback();
    PaUnLock();

  }  // _playing

  return true;
}

bool AudioDeviceLinuxPulse::RecThreadProcess() {
  switch (_timeEventRec.Wait(1000)) {
    case kEventSignaled:
      break;
    case kEventError:
      LOG(LS_WARNING) << "EventWrapper::Wait() failed";
      return true;
    case kEventTimeout:
      return true;
  }

  rtc::CritScope lock(&_critSect);

  if (_startRec) {
    LOG(LS_VERBOSE) << "_startRec true, performing initial actions";

    _recDeviceName = NULL;

    // Set if not default device
    if (_inputDeviceIndex > 0) {
      // Get the recording device name
      _recDeviceName = new char[kAdmMaxDeviceNameSize];
      _deviceIndex = _inputDeviceIndex;
      RecordingDevices();
    }

    PaLock();

    LOG(LS_VERBOSE) << "connecting stream";

    // Connect the stream to a source
    if (LATE(pa_stream_connect_record)(
            _recStream, _recDeviceName, &_recBufferAttr,
            (pa_stream_flags_t)_recStreamFlags) != PA_OK) {
      LOG(LS_ERROR) << "failed to connect rec stream, err="
                    << LATE(pa_context_errno)(_paContext);
    }

    LOG(LS_VERBOSE) << "connected";

    // Wait for state change
    while (LATE(pa_stream_get_state)(_recStream) != PA_STREAM_READY) {
      LATE(pa_threaded_mainloop_wait)(_paMainloop);
    }

    LOG(LS_VERBOSE) << "done";

    // We can now handle read callbacks
    EnableReadCallback();

    PaUnLock();

    // Clear device name
    if (_recDeviceName) {
      delete[] _recDeviceName;
      _recDeviceName = NULL;
    }

    _startRec = false;
    _recording = true;
    _recStartEvent.Set();

    return true;
  }

  if (_recording) {
    // Read data and provide it to VoiceEngine
    if (ReadRecordedData(_tempSampleData, _tempSampleDataSize) == -1) {
      return true;
    }

    _tempSampleData = NULL;
    _tempSampleDataSize = 0;

    PaLock();
    while (true) {
      // Ack the last thing we read
      if (LATE(pa_stream_drop)(_recStream) != 0) {
        LOG(LS_WARNING) << "failed to drop, err="
                        << LATE(pa_context_errno)(_paContext);
      }

      if (LATE(pa_stream_readable_size)(_recStream) <= 0) {
        // Then that was all the data
        break;
      }

      // Else more data.
      const void* sampleData;
      size_t sampleDataSize;

      if (LATE(pa_stream_peek)(_recStream, &sampleData, &sampleDataSize) != 0) {
        _recError = 1;  // triggers callback from module process thread
        LOG(LS_ERROR) << "RECORD_ERROR message posted, error = "
                      << LATE(pa_context_errno)(_paContext);
        break;
      }

      _sndCardRecDelay = (uint32_t)(LatencyUsecs(_recStream) / 1000);

      // Drop lock for sigslot dispatch, which could take a while.
      PaUnLock();
      // Read data and provide it to VoiceEngine
      if (ReadRecordedData(sampleData, sampleDataSize) == -1) {
        return true;
      }
      PaLock();

      // Return to top of loop for the ack and the check for more data.
    }

    EnableReadCallback();
    PaUnLock();

  }  // _recording

  return true;
}

bool AudioDeviceLinuxPulse::KeyPressed() const {
  char szKey[32];
  unsigned int i = 0;
  char state = 0;

  if (!_XDisplay)
    return false;

  // Check key map status
  XQueryKeymap(_XDisplay, szKey);

  // A bit change in keymap means a key is pressed
  for (i = 0; i < sizeof(szKey); i++)
    state |= (szKey[i] ^ _oldKeyState[i]) & szKey[i];

  // Save old state
  memcpy((char*)_oldKeyState, (char*)szKey, sizeof(_oldKeyState));
  return (state != 0);
}
}  // namespace webrtc
