Chromium Code Reviews| 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 7f96fa4f2cd9daaa67abbc0bdc61c63940f78256..9d29a3c2da66a98d1bbfd9bfdce17d36fe181420 100644 |
| --- a/chrome/browser/chromeos/audio_mixer_alsa.cc |
| +++ b/chrome/browser/chromeos/audio_mixer_alsa.cc |
| @@ -8,6 +8,10 @@ |
| #include "base/logging.h" |
| #include "base/task.h" |
| +#include "chrome/browser/browser_process.h" |
| +#include "chrome/browser/browser_thread.h" |
| +#include "chrome/browser/prefs/pref_service.h" |
| +#include "chrome/common/pref_names.h" |
| namespace chromeos { |
| @@ -19,8 +23,6 @@ namespace chromeos { |
| // adjusting that as well. If the PCM element has more volume steps, it allows |
| // for finer granularity in the total volume. |
| -// TODO(davej): Serialize volume/mute to preserve settings when restarting. |
| - |
| typedef long alsa_long_t; // 'long' is required for ALSA API calls. |
| namespace { |
| @@ -29,6 +31,7 @@ const char* kMasterVolume = "Master"; |
| const char* kPCMVolume = "PCM"; |
| const double kDefaultMinVolume = -90.0; |
| const double kDefaultMaxVolume = 0.0; |
| +const double kPrefVolumeNotSet = AudioMixer::kSilenceDb - 100.0; |
| } // namespace |
| @@ -57,8 +60,9 @@ void AudioMixerAlsa::Init(InitDoneCallback* callback) { |
| delete callback; |
| return; |
| } |
| + InitPrefs(); |
| - // Post the task of starting up, which can block for 200-500ms, |
| + // Post the task of starting up, which may block on the order of ms, |
| // so best not to do it on the caller's thread. |
| thread_->message_loop()->PostTask(FROM_HERE, |
| NewRunnableMethod(this, &AudioMixerAlsa::DoInit, callback)); |
| @@ -67,6 +71,7 @@ void AudioMixerAlsa::Init(InitDoneCallback* callback) { |
| bool AudioMixerAlsa::InitSync() { |
| if (!InitThread()) |
| return false; |
| + InitPrefs(); |
| return InitializeAlsaMixer(); |
| } |
| @@ -93,7 +98,10 @@ void AudioMixerAlsa::SetVolumeDb(double vol_db) { |
| AutoLock lock(mixer_state_lock_); |
| if (mixer_state_ != READY) |
| return; |
| + if (vol_db < kSilenceDb) |
| + vol_db = kSilenceDb; |
| DoSetVolumeDb_Locked(vol_db); |
| + volume_pref_.SetValue(vol_db); |
| } |
| bool AudioMixerAlsa::IsMute() const { |
| @@ -111,8 +119,8 @@ void AudioMixerAlsa::SetMute(bool mute) { |
| // Set volume to minimum on mute, since switching the element off does not |
| // always mute as it should. |
| - // TODO(davej): Setting volume to minimum can be removed once switching the |
| - // element off can be guaranteed to work. |
| + // TODO(davej): Remove save_volume_ and setting volume to minimum if |
| + // switching the element off can be guaranteed to mute it. |
| bool old_value = GetElementMuted_Locked(elem_master_); |
| @@ -128,6 +136,7 @@ void AudioMixerAlsa::SetMute(bool mute) { |
| SetElementMuted_Locked(elem_master_, mute); |
| if (elem_pcm_) |
| SetElementMuted_Locked(elem_pcm_, mute); |
| + mute_pref_.SetValue(mute); |
| } |
| AudioMixer::State AudioMixerAlsa::GetState() const { |
| @@ -138,12 +147,26 @@ AudioMixer::State AudioMixerAlsa::GetState() const { |
| return mixer_state_; |
| } |
| +// static |
| +void AudioMixerAlsa::RegisterPrefs(PrefService* local_state) { |
| + if (!local_state->FindPreference(prefs::kAudioVolume)) { |
|
scherkus (not reviewing)
2011/01/14 23:38:50
nit: what about checking for kAudioMute?
davejcool
2011/01/15 03:49:07
Hmmmm... This unraveled an issue with the case of
|
| + local_state->RegisterRealPref(prefs::kAudioVolume, kPrefVolumeNotSet); |
| + local_state->RegisterBooleanPref(prefs::kAudioMute, false); |
| + } |
| +} |
| + |
| //////////////////////////////////////////////////////////////////////////////// |
| // Private functions follow |
| void AudioMixerAlsa::DoInit(InitDoneCallback* callback) { |
| bool success = InitializeAlsaMixer(); |
| + if (success) { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + NewRunnableMethod(this, &AudioMixerAlsa::RestoreVolumeMuteOnUIThread)); |
| + } |
| + |
| if (callback) { |
| callback->Run(success); |
| delete callback; |
| @@ -168,6 +191,13 @@ bool AudioMixerAlsa::InitThread() { |
| return true; |
| } |
| +void AudioMixerAlsa::InitPrefs() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + PrefService* prefs = g_browser_process->local_state(); |
| + volume_pref_.Init(prefs::kAudioVolume, prefs, NULL); |
| + mute_pref_.Init(prefs::kAudioMute, prefs, NULL); |
| +} |
| + |
| bool AudioMixerAlsa::InitializeAlsaMixer() { |
| AutoLock lock(mixer_state_lock_); |
| if (mixer_state_ != INITIALIZING) |
| @@ -241,6 +271,35 @@ void AudioMixerAlsa::FreeAlsaMixer() { |
| } |
| } |
| +void AudioMixerAlsa::DoSetVolumeMute(double volume, bool mute) { |
| + AutoLock lock(mixer_state_lock_); |
| + if (mixer_state_ != READY) |
| + return; |
| + |
| + VLOG(1) << "Setting volume to " << volume << "and mute to " << mute; |
| + if (mute) { |
| + save_volume_ = volume; |
| + DoSetVolumeDb_Locked(min_volume_); |
| + } else { |
| + DoSetVolumeDb_Locked(volume); |
| + } |
| + |
| + SetElementMuted_Locked(elem_master_, mute); |
| + if (elem_pcm_) |
| + SetElementMuted_Locked(elem_pcm_, mute); |
| +} |
| + |
| +void AudioMixerAlsa::RestoreVolumeMuteOnUIThread() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + if (volume_pref_.GetValue() < kSilenceDb) |
| + return; |
| + |
| + // This happens during init, so set the volume off the UI thread. |
| + thread_->message_loop()->PostTask(FROM_HERE, |
| + NewRunnableMethod(this, &AudioMixerAlsa::DoSetVolumeMute, |
| + volume_pref_.GetValue(), mute_pref_.GetValue())); |
| +} |
| + |
| double AudioMixerAlsa::DoGetVolumeDb_Locked() const { |
| double vol_total = 0.0; |
| GetElementVolume_Locked(elem_master_, &vol_total); |
| @@ -258,7 +317,6 @@ void AudioMixerAlsa::DoSetVolumeDb_Locked(double vol_db) { |
| // If a PCM volume slider exists, then first set the Master volume to the |
| // nearest volume >= requested volume, then adjust PCM volume down to get |
| // closer to the requested volume. |
| - |
| if (elem_pcm_) { |
| SetElementVolume_Locked(elem_master_, vol_db, &actual_vol, 0.9999f); |
| SetElementVolume_Locked(elem_pcm_, vol_db - actual_vol, NULL, 0.5f); |
| @@ -273,7 +331,7 @@ snd_mixer_elem_t* AudioMixerAlsa::FindElementWithName_Locked( |
| snd_mixer_selem_id_t* sid; |
| // Using id_malloc/id_free API instead of id_alloca since the latter gives the |
| - // warning: the address of 'sid' will always evaluate as 'true' |
| + // warning: the address of 'sid' will always evaluate as 'true'. |
| if (snd_mixer_selem_id_malloc(&sid)) |
| return NULL; |