/*
 *  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 <stddef.h>

#include "modules/audio_device/linux/audio_device_pulse_linux.h"
#include "modules/audio_device/linux/audio_mixer_manager_pulse_linux.h"
#include "modules/audio_device/linux/latebindingsymboltable_linux.h"
#include "modules/audio_device/linux/pulseaudiosymboltable_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_.IsCurrent());
  RTC_LOG(LS_INFO) << __FUNCTION__ << " destroyed";

  Close();
}

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

int32_t AudioMixerManagerLinuxPulse::SetPulseAudioObjects(
    pa_threaded_mainloop* mainloop,
    pa_context* context) {
  RTC_DCHECK(thread_checker_.IsCurrent());
  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_.IsCurrent());
  RTC_LOG(LS_VERBOSE) << __FUNCTION__;

  CloseSpeaker();
  CloseMicrophone();

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

  return 0;
}

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

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

  return 0;
}

int32_t AudioMixerManagerLinuxPulse::CloseMicrophone() {
  RTC_DCHECK(thread_checker_.IsCurrent());
  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_.IsCurrent());
  RTC_LOG(LS_VERBOSE)
      << "AudioMixerManagerLinuxPulse::SetPlayStream(playStream)";

  _paPlayStream = playStream;
  return 0;
}

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

  _paRecStream = recStream;
  return 0;
}

int32_t AudioMixerManagerLinuxPulse::OpenSpeaker(uint16_t deviceIndex) {
  RTC_DCHECK(thread_checker_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  RTC_LOG(LS_INFO) << __FUNCTION__;

  return (_paOutputDeviceIndex != -1);
}

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

  return (_paInputDeviceIndex != -1);
}

int32_t AudioMixerManagerLinuxPulse::SetSpeakerVolume(uint32_t volume) {
  RTC_DCHECK(thread_checker_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  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_.IsCurrent());
  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
