/*
 *  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 "modules/audio_device/linux/audio_device_pulse_linux.h"
#include "modules/audio_device/linux/audio_mixer_manager_pulse_linux.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

// 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, \
              GetPulseSymbolTable(), sym)

namespace webrtc {

class AutoPulseLock {
 public:
  explicit AutoPulseLock(pa_threaded_mainloop* pa_mainloop)
      : pa_mainloop_(pa_mainloop) {
    LATE(pa_threaded_mainloop_lock)(pa_mainloop_);
  }

  ~AutoPulseLock() { LATE(pa_threaded_mainloop_unlock)(pa_mainloop_); }

 private:
  pa_threaded_mainloop* const pa_mainloop_;
};

AudioMixerManagerLinuxPulse::AudioMixerManagerLinuxPulse()
    : _paOutputDeviceIndex(-1),
      _paInputDeviceIndex(-1),
      _paPlayStream(NULL),
      _paRecStream(NULL),
      _paMainloop(NULL),
      _paContext(NULL),
      _paVolume(0),
      _paMute(0),
      _paVolSteps(0),
      _paSpeakerMute(false),
      _paSpeakerVolume(PA_VOLUME_NORM),
      _paChannels(0),
      _paObjectsSet(false) {
  RTC_LOG(LS_INFO) << __FUNCTION__ << " created";
}

AudioMixerManagerLinuxPulse::~AudioMixerManagerLinuxPulse() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_INFO) << __FUNCTION__ << " destroyed";

  Close();
}

// ===========================================================================
//                                    PUBLIC METHODS
// ===========================================================================

int32_t AudioMixerManagerLinuxPulse::SetPulseAudioObjects(
    pa_threaded_mainloop* mainloop,
    pa_context* context) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  if (!mainloop || !context) {
    RTC_LOG(LS_ERROR) << "could not set PulseAudio objects for mixer";
    return -1;
  }

  _paMainloop = mainloop;
  _paContext = context;
  _paObjectsSet = true;

  RTC_LOG(LS_VERBOSE) << "the PulseAudio objects for the mixer has been set";

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::Close() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  CloseSpeaker();
  CloseMicrophone();

  _paMainloop = NULL;
  _paContext = NULL;
  _paObjectsSet = false;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::CloseSpeaker() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  // Reset the index to -1
  _paOutputDeviceIndex = -1;
  _paPlayStream = NULL;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::CloseMicrophone() {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  // Reset the index to -1
  _paInputDeviceIndex = -1;
  _paRecStream = NULL;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetPlayStream(pa_stream* playStream) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::SetPlayStream(playStream)";

  _paPlayStream = playStream;
  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetRecStream(pa_stream* recStream) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetRecStream(recStream)";

  _paRecStream = recStream;
  return 0;
}

int32_t AudioMixerManagerLinuxPulse::OpenSpeaker(uint16_t deviceIndex) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::OpenSpeaker(deviceIndex="
                      << deviceIndex << ")";

  // No point in opening the speaker
  // if PA objects have not been set
  if (!_paObjectsSet) {
    RTC_LOG(LS_ERROR) << "PulseAudio objects has not been set";
    return -1;
  }

  // Set the index for the PulseAudio
  // output device to control
  _paOutputDeviceIndex = deviceIndex;

  RTC_LOG(LS_VERBOSE) << "the output mixer device is now open";

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::OpenMicrophone(uint16_t deviceIndex) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::OpenMicrophone(deviceIndex="
      << deviceIndex << ")";

  // No point in opening the microphone
  // if PA objects have not been set
  if (!_paObjectsSet) {
    RTC_LOG(LS_ERROR) << "PulseAudio objects have not been set";
    return -1;
  }

  // Set the index for the PulseAudio
  // input device to control
  _paInputDeviceIndex = deviceIndex;

  RTC_LOG(LS_VERBOSE) << "the input mixer device is now open";

  return 0;
}

bool AudioMixerManagerLinuxPulse::SpeakerIsInitialized() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_INFO) << __FUNCTION__;

  return (_paOutputDeviceIndex != -1);
}

bool AudioMixerManagerLinuxPulse::MicrophoneIsInitialized() const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_INFO) << __FUNCTION__;

  return (_paInputDeviceIndex != -1);
}

int32_t AudioMixerManagerLinuxPulse::SetSpeakerVolume(uint32_t volume) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetSpeakerVolume(volume="
                      << volume << ")";

  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  bool setFailed(false);

  if (_paPlayStream &&
      (LATE(pa_stream_get_state)(_paPlayStream) != PA_STREAM_UNCONNECTED)) {
    // We can only really set the volume if we have a connected stream
    AutoPulseLock auto_lock(_paMainloop);

    // Get the number of channels from the sample specification
    const pa_sample_spec* spec = LATE(pa_stream_get_sample_spec)(_paPlayStream);
    if (!spec) {
      RTC_LOG(LS_ERROR) << "could not get sample specification";
      return -1;
    }

    // Set the same volume for all channels
    pa_cvolume cVolumes;
    LATE(pa_cvolume_set)(&cVolumes, spec->channels, volume);

    pa_operation* paOperation = NULL;
    paOperation = LATE(pa_context_set_sink_input_volume)(
        _paContext, LATE(pa_stream_get_index)(_paPlayStream), &cVolumes,
        PaSetVolumeCallback, NULL);
    if (!paOperation) {
      setFailed = true;
    }

    // Don't need to wait for the completion
    LATE(pa_operation_unref)(paOperation);
  } else {
    // We have not created a stream or it's not connected to the sink
    // Save the volume to be set at connection
    _paSpeakerVolume = volume;
  }

  if (setFailed) {
    RTC_LOG(LS_WARNING) << "could not set speaker volume, error="
                        << LATE(pa_context_errno)(_paContext);

    return -1;
  }

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SpeakerVolume(uint32_t& volume) const {
  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  if (_paPlayStream &&
      (LATE(pa_stream_get_state)(_paPlayStream) != PA_STREAM_UNCONNECTED)) {
    // We can only get the volume if we have a connected stream
    if (!GetSinkInputInfo())
      return -1;

    AutoPulseLock auto_lock(_paMainloop);
    volume = static_cast<uint32_t>(_paVolume);
  } else {
    AutoPulseLock auto_lock(_paMainloop);
    volume = _paSpeakerVolume;
  }

  RTC_LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SpeakerVolume() => vol="
                      << volume;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::MaxSpeakerVolume(
    uint32_t& maxVolume) const {
  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  // PA_VOLUME_NORM corresponds to 100% (0db)
  // but PA allows up to 150 db amplification
  maxVolume = static_cast<uint32_t>(PA_VOLUME_NORM);

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::MinSpeakerVolume(
    uint32_t& minVolume) const {
  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  minVolume = static_cast<uint32_t>(PA_VOLUME_MUTED);

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SpeakerVolumeIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  // Always available in Pulse Audio
  available = true;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SpeakerMuteIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  // Always available in Pulse Audio
  available = true;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetSpeakerMute(bool enable) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE) << "AudioMixerManagerLinuxPulse::SetSpeakerMute(enable="
                      << enable << ")";

  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  bool setFailed(false);

  if (_paPlayStream &&
      (LATE(pa_stream_get_state)(_paPlayStream) != PA_STREAM_UNCONNECTED)) {
    // We can only really mute if we have a connected stream
    AutoPulseLock auto_lock(_paMainloop);

    pa_operation* paOperation = NULL;
    paOperation = LATE(pa_context_set_sink_input_mute)(
        _paContext, LATE(pa_stream_get_index)(_paPlayStream), (int)enable,
        PaSetVolumeCallback, NULL);
    if (!paOperation) {
      setFailed = true;
    }

    // Don't need to wait for the completion
    LATE(pa_operation_unref)(paOperation);
  } else {
    // We have not created a stream or it's not connected to the sink
    // Save the mute status to be set at connection
    _paSpeakerMute = enable;
  }

  if (setFailed) {
    RTC_LOG(LS_WARNING) << "could not mute speaker, error="
                        << LATE(pa_context_errno)(_paContext);
    return -1;
  }

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SpeakerMute(bool& enabled) const {
  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  if (_paPlayStream &&
      (LATE(pa_stream_get_state)(_paPlayStream) != PA_STREAM_UNCONNECTED)) {
    // We can only get the mute status if we have a connected stream
    if (!GetSinkInputInfo())
      return -1;

    enabled = static_cast<bool>(_paMute);
  } else {
    enabled = _paSpeakerMute;
  }
  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::SpeakerMute() => enabled=" << enabled;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::StereoPlayoutIsAvailable(bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_paOutputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "output device index has not been set";
    return -1;
  }

  uint32_t deviceIndex = (uint32_t)_paOutputDeviceIndex;

  {
    AutoPulseLock auto_lock(_paMainloop);

    // Get the actual stream device index if we have a connected stream
    // The device used by the stream can be changed
    // during the call
    if (_paPlayStream &&
        (LATE(pa_stream_get_state)(_paPlayStream) != PA_STREAM_UNCONNECTED)) {
      deviceIndex = LATE(pa_stream_get_device_index)(_paPlayStream);
    }
  }

  if (!GetSinkInfoByIndex(deviceIndex))
    return -1;

  available = static_cast<bool>(_paChannels == 2);

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable(
    bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  uint32_t deviceIndex = (uint32_t)_paInputDeviceIndex;

  AutoPulseLock auto_lock(_paMainloop);

  // Get the actual stream device index if we have a connected stream
  // The device used by the stream can be changed
  // during the call
  if (_paRecStream &&
      (LATE(pa_stream_get_state)(_paRecStream) != PA_STREAM_UNCONNECTED)) {
    deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
  }

  pa_operation* paOperation = NULL;

  // Get info for this source
  // We want to know if the actual device can record in stereo
  paOperation = LATE(pa_context_get_source_info_by_index)(
      _paContext, deviceIndex, PaSourceInfoCallback, (void*)this);

  WaitForOperationCompletion(paOperation);

  available = static_cast<bool>(_paChannels == 2);

  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::StereoRecordingIsAvailable()"
      << " => available=" << available;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::MicrophoneMuteIsAvailable(
    bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  // Always available in Pulse Audio
  available = true;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetMicrophoneMute(bool enable) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::SetMicrophoneMute(enable=" << enable
      << ")";

  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  bool setFailed(false);
  pa_operation* paOperation = NULL;

  uint32_t deviceIndex = (uint32_t)_paInputDeviceIndex;

  AutoPulseLock auto_lock(_paMainloop);

  // Get the actual stream device index if we have a connected stream
  // The device used by the stream can be changed
  // during the call
  if (_paRecStream &&
      (LATE(pa_stream_get_state)(_paRecStream) != PA_STREAM_UNCONNECTED)) {
    deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
  }

  // Set mute switch for the source
  paOperation = LATE(pa_context_set_source_mute_by_index)(
      _paContext, deviceIndex, enable, PaSetVolumeCallback, NULL);

  if (!paOperation) {
    setFailed = true;
  }

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

  if (setFailed) {
    RTC_LOG(LS_WARNING) << "could not mute microphone, error="
                        << LATE(pa_context_errno)(_paContext);
    return -1;
  }

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::MicrophoneMute(bool& enabled) const {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  uint32_t deviceIndex = (uint32_t)_paInputDeviceIndex;

  {
    AutoPulseLock auto_lock(_paMainloop);
    // Get the actual stream device index if we have a connected stream
    // The device used by the stream can be changed
    // during the call
    if (_paRecStream &&
        (LATE(pa_stream_get_state)(_paRecStream) != PA_STREAM_UNCONNECTED)) {
      deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
    }
  }

  if (!GetSourceInfoByIndex(deviceIndex))
    return -1;

  enabled = static_cast<bool>(_paMute);

  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::MicrophoneMute() => enabled=" << enabled;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::MicrophoneVolumeIsAvailable(
    bool& available) {
  RTC_DCHECK(thread_checker_.CalledOnValidThread());
  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  // Always available in Pulse Audio
  available = true;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::SetMicrophoneVolume(uint32_t volume) {
  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::SetMicrophoneVolume(volume=" << volume
      << ")";

  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  // Unlike output streams, input streams have no concept of a stream
  // volume, only a device volume. So we have to change the volume of the
  // device itself.

  // The device may have a different number of channels than the stream and
  // their mapping may be different, so we don't want to use the channel
  // count from our sample spec. We could use PA_CHANNELS_MAX to cover our
  // bases, and the server allows that even if the device's channel count
  // is lower, but some buggy PA clients don't like that (the pavucontrol
  // on Hardy dies in an assert if the channel count is different). So
  // instead we look up the actual number of channels that the device has.
  AutoPulseLock auto_lock(_paMainloop);
  uint32_t deviceIndex = (uint32_t)_paInputDeviceIndex;

  // Get the actual stream device index if we have a connected stream
  // The device used by the stream can be changed
  // during the call
  if (_paRecStream &&
      (LATE(pa_stream_get_state)(_paRecStream) != PA_STREAM_UNCONNECTED)) {
    deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
  }

  bool setFailed(false);
  pa_operation* paOperation = NULL;

  // Get the number of channels for this source
  paOperation = LATE(pa_context_get_source_info_by_index)(
      _paContext, deviceIndex, PaSourceInfoCallback, (void*)this);

  WaitForOperationCompletion(paOperation);

  uint8_t channels = _paChannels;
  pa_cvolume cVolumes;
  LATE(pa_cvolume_set)(&cVolumes, channels, volume);

  // Set the volume for the source
  paOperation = LATE(pa_context_set_source_volume_by_index)(
      _paContext, deviceIndex, &cVolumes, PaSetVolumeCallback, NULL);

  if (!paOperation) {
    setFailed = true;
  }

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

  if (setFailed) {
    RTC_LOG(LS_WARNING) << "could not set microphone volume, error="
                        << LATE(pa_context_errno)(_paContext);
    return -1;
  }

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::MicrophoneVolume(uint32_t& volume) const {
  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  uint32_t deviceIndex = (uint32_t)_paInputDeviceIndex;

  {
    AutoPulseLock auto_lock(_paMainloop);
    // Get the actual stream device index if we have a connected stream.
    // The device used by the stream can be changed during the call.
    if (_paRecStream &&
        (LATE(pa_stream_get_state)(_paRecStream) != PA_STREAM_UNCONNECTED)) {
      deviceIndex = LATE(pa_stream_get_device_index)(_paRecStream);
    }
  }

  if (!GetSourceInfoByIndex(deviceIndex))
    return -1;

  {
    AutoPulseLock auto_lock(_paMainloop);
    volume = static_cast<uint32_t>(_paVolume);
  }

  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::MicrophoneVolume() => vol=" << volume;

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::MaxMicrophoneVolume(
    uint32_t& maxVolume) const {
  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  // PA_VOLUME_NORM corresponds to 100% (0db)
  // PA allows up to 150 db amplification (PA_VOLUME_MAX)
  // but that doesn't work well for all sound cards
  maxVolume = static_cast<uint32_t>(PA_VOLUME_NORM);

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::MinMicrophoneVolume(
    uint32_t& minVolume) const {
  if (_paInputDeviceIndex == -1) {
    RTC_LOG(LS_WARNING) << "input device index has not been set";
    return -1;
  }

  minVolume = static_cast<uint32_t>(PA_VOLUME_MUTED);

  return 0;
}

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

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

void AudioMixerManagerLinuxPulse::PaSinkInputInfoCallback(
    pa_context* /*c*/,
    const pa_sink_input_info* i,
    int eol,
    void* pThis) {
  static_cast<AudioMixerManagerLinuxPulse*>(pThis)
      ->PaSinkInputInfoCallbackHandler(i, eol);
}

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

void AudioMixerManagerLinuxPulse::PaSetVolumeCallback(pa_context* c,
                                                      int success,
                                                      void* /*pThis*/) {
  if (!success) {
    RTC_LOG(LS_ERROR) << "failed to set volume";
  }
}

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

  _paChannels = i->channel_map.channels;   // Get number of channels
  pa_volume_t paVolume = PA_VOLUME_MUTED;  // Minimum possible value.
  for (int j = 0; j < _paChannels; ++j) {
    if (paVolume < i->volume.values[j]) {
      paVolume = i->volume.values[j];
    }
  }
  _paVolume = paVolume;  // get the max volume for any channel
  _paMute = i->mute;     // get mute status

  // supported since PA 0.9.15
  //_paVolSteps = i->n_volume_steps; // get the number of volume steps
  // default value is PA_VOLUME_NORM+1
  _paVolSteps = PA_VOLUME_NORM + 1;
}

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

  _paChannels = i->channel_map.channels;   // Get number of channels
  pa_volume_t paVolume = PA_VOLUME_MUTED;  // Minimum possible value.
  for (int j = 0; j < _paChannels; ++j) {
    if (paVolume < i->volume.values[j]) {
      paVolume = i->volume.values[j];
    }
  }
  _paVolume = paVolume;  // Get the max volume for any channel
  _paMute = i->mute;     // Get mute status
}

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

  _paChannels = i->channel_map.channels;   // Get number of channels
  pa_volume_t paVolume = PA_VOLUME_MUTED;  // Minimum possible value.
  for (int j = 0; j < _paChannels; ++j) {
    if (paVolume < i->volume.values[j]) {
      paVolume = i->volume.values[j];
    }
  }
  _paVolume = paVolume;  // Get the max volume for any channel
  _paMute = i->mute;     // Get mute status

  // supported since PA 0.9.15
  //_paVolSteps = i->n_volume_steps; // Get the number of volume steps
  // default value is PA_VOLUME_NORM+1
  _paVolSteps = PA_VOLUME_NORM + 1;
}

void AudioMixerManagerLinuxPulse::WaitForOperationCompletion(
    pa_operation* paOperation) const {
  while (LATE(pa_operation_get_state)(paOperation) == PA_OPERATION_RUNNING) {
    LATE(pa_threaded_mainloop_wait)(_paMainloop);
  }

  LATE(pa_operation_unref)(paOperation);
}

bool AudioMixerManagerLinuxPulse::GetSinkInputInfo() const {
  pa_operation* paOperation = NULL;

  AutoPulseLock auto_lock(_paMainloop);
  // Get info for this stream (sink input).
  paOperation = LATE(pa_context_get_sink_input_info)(
      _paContext, LATE(pa_stream_get_index)(_paPlayStream),
      PaSinkInputInfoCallback, (void*)this);

  WaitForOperationCompletion(paOperation);
  return true;
}

bool AudioMixerManagerLinuxPulse::GetSinkInfoByIndex(int device_index) const {
  pa_operation* paOperation = NULL;

  AutoPulseLock auto_lock(_paMainloop);
  paOperation = LATE(pa_context_get_sink_info_by_index)(
      _paContext, device_index, PaSinkInfoCallback, (void*)this);

  WaitForOperationCompletion(paOperation);
  return true;
}

bool AudioMixerManagerLinuxPulse::GetSourceInfoByIndex(int device_index) const {
  pa_operation* paOperation = NULL;

  AutoPulseLock auto_lock(_paMainloop);
  paOperation = LATE(pa_context_get_source_info_by_index)(
      _paContext, device_index, PaSourceInfoCallback, (void*)this);

  WaitForOperationCompletion(paOperation);
  return true;
}

}  // namespace webrtc
