| Index: chrome/browser/chromeos/audio_mixer_alsa.cc
|
| diff --git a/chrome/browser/chromeos/audio_mixer_alsa.cc b/chrome/browser/chromeos/audio_mixer_alsa.cc
|
| index 70c47a5bbe078e57734c2cb149a0a5f76d414e71..0b8d78844e9285a5cadd2afeb2430bf48982177f 100644
|
| --- a/chrome/browser/chromeos/audio_mixer_alsa.cc
|
| +++ b/chrome/browser/chromeos/audio_mixer_alsa.cc
|
| @@ -4,6 +4,8 @@
|
|
|
| #include "chrome/browser/chromeos/audio_mixer_alsa.h"
|
|
|
| +#include <cmath>
|
| +
|
| #include <alsa/asoundlib.h>
|
|
|
| #include "base/logging.h"
|
| @@ -125,8 +127,13 @@ void AudioMixerAlsa::SetVolumeDb(double vol_db) {
|
| base::AutoLock lock(mixer_state_lock_);
|
| if (mixer_state_ != READY)
|
| return;
|
| - if (vol_db < kSilenceDb)
|
| +
|
| + if (vol_db < kSilenceDb || isnan(vol_db)) {
|
| + if (isnan(vol_db))
|
| + LOG(WARNING) << "Got request to set volume to NaN";
|
| vol_db = kSilenceDb;
|
| + }
|
| +
|
| DoSetVolumeDb_Locked(vol_db);
|
| prefs_->SetDouble(prefs::kAudioVolume, vol_db);
|
| }
|
| @@ -270,7 +277,14 @@ bool AudioMixerAlsa::InitializeAlsaMixer() {
|
| if (elem_master_) {
|
| alsa_long_t long_lo = static_cast<alsa_long_t>(kDefaultMinVolume * 100);
|
| alsa_long_t long_hi = static_cast<alsa_long_t>(kDefaultMaxVolume * 100);
|
| - snd_mixer_selem_get_playback_dB_range(elem_master_, &long_lo, &long_hi);
|
| + err = snd_mixer_selem_get_playback_dB_range(
|
| + elem_master_, &long_lo, &long_hi);
|
| + if (err != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_get_playback_dB_range() failed "
|
| + << "for master: " << snd_strerror(err);
|
| + snd_mixer_close(handle);
|
| + return false;
|
| + }
|
| min_volume_ = static_cast<double>(long_lo) / 100.0;
|
| max_volume_ = static_cast<double>(long_hi) / 100.0;
|
| } else {
|
| @@ -283,7 +297,13 @@ bool AudioMixerAlsa::InitializeAlsaMixer() {
|
| if (elem_pcm_) {
|
| alsa_long_t long_lo = static_cast<alsa_long_t>(kDefaultMinVolume * 100);
|
| alsa_long_t long_hi = static_cast<alsa_long_t>(kDefaultMaxVolume * 100);
|
| - snd_mixer_selem_get_playback_dB_range(elem_pcm_, &long_lo, &long_hi);
|
| + err = snd_mixer_selem_get_playback_dB_range(elem_pcm_, &long_lo, &long_hi);
|
| + if (err != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_get_playback_dB_range() failed for PCM: "
|
| + << snd_strerror(err);
|
| + snd_mixer_close(handle);
|
| + return false;
|
| + }
|
| min_volume_ += static_cast<double>(long_lo) / 100.0;
|
| max_volume_ += static_cast<double>(long_hi) / 100.0;
|
| }
|
| @@ -312,7 +332,7 @@ void AudioMixerAlsa::DoSetVolumeMute(double pref_volume, int pref_mute) {
|
| // If volume or mute are invalid, set them now to the current actual values.
|
| if (!PrefVolumeValid(pref_volume))
|
| pref_volume = DoGetVolumeDb_Locked();
|
| - bool mute;
|
| + bool mute = false;
|
| if (pref_mute == kPrefMuteInvalid)
|
| mute = GetElementMuted_Locked(elem_master_);
|
| else
|
| @@ -348,10 +368,11 @@ void AudioMixerAlsa::RestoreVolumeMuteOnUIThread() {
|
|
|
| double AudioMixerAlsa::DoGetVolumeDb_Locked() const {
|
| double vol_total = 0.0;
|
| - GetElementVolume_Locked(elem_master_, &vol_total);
|
| + if (!GetElementVolume_Locked(elem_master_, &vol_total))
|
| + return 0.0;
|
|
|
| double vol_pcm = 0.0;
|
| - if (elem_pcm_ && (GetElementVolume_Locked(elem_pcm_, &vol_pcm)))
|
| + if (elem_pcm_ && GetElementVolume_Locked(elem_pcm_, &vol_pcm))
|
| vol_total += vol_pcm;
|
|
|
| return vol_total;
|
| @@ -396,11 +417,15 @@ snd_mixer_elem_t* AudioMixerAlsa::FindElementWithName_Locked(
|
| bool AudioMixerAlsa::GetElementVolume_Locked(snd_mixer_elem_t* elem,
|
| double* current_vol) const {
|
| alsa_long_t long_vol = 0;
|
| - snd_mixer_selem_get_playback_dB(elem,
|
| - static_cast<snd_mixer_selem_channel_id_t>(0),
|
| - &long_vol);
|
| - *current_vol = static_cast<double>(long_vol) / 100.0;
|
| + int alsa_result = snd_mixer_selem_get_playback_dB(
|
| + elem, static_cast<snd_mixer_selem_channel_id_t>(0), &long_vol);
|
| + if (alsa_result != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_get_playback_dB() failed: "
|
| + << snd_strerror(alsa_result);
|
| + return false;
|
| + }
|
|
|
| + *current_vol = static_cast<double>(long_vol) / 100.0;
|
| return true;
|
| }
|
|
|
| @@ -410,14 +435,27 @@ bool AudioMixerAlsa::SetElementVolume_Locked(snd_mixer_elem_t* elem,
|
| double rounding_bias) {
|
| alsa_long_t vol_lo = 0;
|
| alsa_long_t vol_hi = 0;
|
| - snd_mixer_selem_get_playback_volume_range(elem, &vol_lo, &vol_hi);
|
| + int alsa_result =
|
| + snd_mixer_selem_get_playback_volume_range(elem, &vol_lo, &vol_hi);
|
| + if (alsa_result != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_get_playback_volume_range() failed: "
|
| + << snd_strerror(alsa_result);
|
| + return false;
|
| + }
|
| alsa_long_t vol_range = vol_hi - vol_lo;
|
| if (vol_range <= 0)
|
| return false;
|
|
|
| alsa_long_t db_lo_int = 0;
|
| alsa_long_t db_hi_int = 0;
|
| - snd_mixer_selem_get_playback_dB_range(elem, &db_lo_int, &db_hi_int);
|
| + alsa_result =
|
| + snd_mixer_selem_get_playback_dB_range(elem, &db_lo_int, &db_hi_int);
|
| + if (alsa_result != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_get_playback_dB_range() failed: "
|
| + << snd_strerror(alsa_result);
|
| + return false;
|
| + }
|
| +
|
| double db_lo = static_cast<double>(db_lo_int) / 100.0;
|
| double db_hi = static_cast<double>(db_hi_int) / 100.0;
|
| double db_step = static_cast<double>(db_hi - db_lo) / vol_range;
|
| @@ -429,7 +467,12 @@ bool AudioMixerAlsa::SetElementVolume_Locked(snd_mixer_elem_t* elem,
|
|
|
| alsa_long_t value = static_cast<alsa_long_t>(rounding_bias +
|
| (new_vol - db_lo) / db_step) + vol_lo;
|
| - snd_mixer_selem_set_playback_volume_all(elem, value);
|
| + alsa_result = snd_mixer_selem_set_playback_volume_all(elem, value);
|
| + if (alsa_result != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_set_playback_volume_all() failed: "
|
| + << snd_strerror(alsa_result);
|
| + return false;
|
| + }
|
|
|
| VLOG(1) << "Set volume " << snd_mixer_selem_get_name(elem)
|
| << " to " << new_vol << " ==> " << (value - vol_lo) * db_step + db_lo
|
| @@ -437,10 +480,13 @@ bool AudioMixerAlsa::SetElementVolume_Locked(snd_mixer_elem_t* elem,
|
|
|
| if (actual_vol) {
|
| alsa_long_t volume = vol_lo;
|
| - snd_mixer_selem_get_playback_volume(
|
| - elem,
|
| - static_cast<snd_mixer_selem_channel_id_t>(0),
|
| - &volume);
|
| + alsa_result = snd_mixer_selem_get_playback_volume(
|
| + elem, static_cast<snd_mixer_selem_channel_id_t>(0), &volume);
|
| + if (alsa_result != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_get_playback_volume() failed: "
|
| + << snd_strerror(alsa_result);
|
| + return false;
|
| + }
|
| *actual_vol = db_lo + (volume - vol_lo) * db_step;
|
|
|
| VLOG(1) << "Actual volume " << snd_mixer_selem_get_name(elem)
|
| @@ -451,19 +497,26 @@ bool AudioMixerAlsa::SetElementVolume_Locked(snd_mixer_elem_t* elem,
|
|
|
| bool AudioMixerAlsa::GetElementMuted_Locked(snd_mixer_elem_t* elem) const {
|
| int enabled = 0;
|
| - snd_mixer_selem_get_playback_switch(
|
| - elem,
|
| - static_cast<snd_mixer_selem_channel_id_t>(0),
|
| - &enabled);
|
| + int alsa_result = snd_mixer_selem_get_playback_switch(
|
| + elem, static_cast<snd_mixer_selem_channel_id_t>(0), &enabled);
|
| + if (alsa_result != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_get_playback_switch() failed: "
|
| + << snd_strerror(alsa_result);
|
| + return false;
|
| + }
|
| return (enabled) ? false : true;
|
| }
|
|
|
| void AudioMixerAlsa::SetElementMuted_Locked(snd_mixer_elem_t* elem, bool mute) {
|
| int enabled = mute ? 0 : 1;
|
| - snd_mixer_selem_set_playback_switch_all(elem, enabled);
|
| -
|
| - VLOG(1) << "Set playback switch " << snd_mixer_selem_get_name(elem)
|
| - << " to " << enabled;
|
| + int alsa_result = snd_mixer_selem_set_playback_switch_all(elem, enabled);
|
| + if (alsa_result != 0) {
|
| + LOG(WARNING) << "snd_mixer_selem_set_playback_switch_all() failed: "
|
| + << snd_strerror(alsa_result);
|
| + } else {
|
| + VLOG(1) << "Set playback switch " << snd_mixer_selem_get_name(elem)
|
| + << " to " << enabled;
|
| + }
|
| }
|
|
|
| } // namespace chromeos
|
|
|