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..f9aa52e210e1a02145af2fd1dce977f49e717806 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 = -999.0; |
| } // namespace |
| @@ -90,10 +93,13 @@ bool AudioMixerAlsa::GetVolumeLimits(double* vol_min, double* vol_max) { |
| } |
| void AudioMixerAlsa::SetVolumeDb(double vol_db) { |
| - AutoLock lock(mixer_state_lock_); |
| - if (mixer_state_ != READY) |
| - return; |
| - DoSetVolumeDb_Locked(vol_db); |
| + { |
| + AutoLock lock(mixer_state_lock_); |
| + if (mixer_state_ != READY) |
| + return; |
| + DoSetVolumeDb_Locked(vol_db); |
| + } |
| + SaveVolume(vol_db); |
| } |
| bool AudioMixerAlsa::IsMute() const { |
| @@ -104,30 +110,34 @@ bool AudioMixerAlsa::IsMute() const { |
| } |
| void AudioMixerAlsa::SetMute(bool mute) { |
| - AutoLock lock(mixer_state_lock_); |
| - if (mixer_state_ != READY) |
| - return; |
| + { |
| + AutoLock lock(mixer_state_lock_); |
| + |
| + if (mixer_state_ != READY) |
| + return; |
| - // Set volume to minimum on mute, since switching the element off does not |
| - // always mute as it should. |
| + // 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_); |
| + bool old_value = GetElementMuted_Locked(elem_master_); |
| - if (old_value != mute) { |
| - if (mute) { |
| - save_volume_ = DoGetVolumeDb_Locked(); |
| - DoSetVolumeDb_Locked(min_volume_); |
| - } else { |
| - DoSetVolumeDb_Locked(save_volume_); |
| + if (old_value != mute) { |
| + if (mute) { |
| + save_volume_ = DoGetVolumeDb_Locked(); |
| + DoSetVolumeDb_Locked(min_volume_); |
| + } else { |
| + DoSetVolumeDb_Locked(save_volume_); |
| + } |
| } |
| - } |
| - SetElementMuted_Locked(elem_master_, mute); |
| - if (elem_pcm_) |
| - SetElementMuted_Locked(elem_pcm_, mute); |
| + SetElementMuted_Locked(elem_master_, mute); |
| + if (elem_pcm_) |
| + SetElementMuted_Locked(elem_pcm_, mute); |
| + } |
| + SaveMute(mute); |
| } |
| AudioMixer::State AudioMixerAlsa::GetState() const { |
| @@ -144,6 +154,12 @@ AudioMixer::State AudioMixerAlsa::GetState() const { |
| void AudioMixerAlsa::DoInit(InitDoneCallback* callback) { |
| bool success = InitializeAlsaMixer(); |
| + if (success) { |
| + BrowserThread::PostTask( |
| + BrowserThread::UI, FROM_HERE, |
| + NewRunnableMethod(this, &AudioMixerAlsa::RestoreVolumeMute)); |
| + } |
| + |
| if (callback) { |
| callback->Run(success); |
| delete callback; |
| @@ -241,6 +257,24 @@ 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); |
| +} |
| + |
| double AudioMixerAlsa::DoGetVolumeDb_Locked() const { |
| double vol_total = 0.0; |
| GetElementVolume_Locked(elem_master_, &vol_total); |
| @@ -362,5 +396,62 @@ void AudioMixerAlsa::SetElementMuted_Locked(snd_mixer_elem_t* elem, bool mute) { |
| << " to " << enabled; |
| } |
| +void AudioMixerAlsa::RestoreVolumeMute() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + if (!g_browser_process) |
| + return; |
| + |
| + PrefService* local_state = g_browser_process->local_state(); |
|
scherkus (not reviewing)
2011/01/13 00:54:52
take a look at PrefMember which wraps up all these
davejcool
2011/01/13 21:31:14
Thanks for the PrefMember pointer! This greatly s
|
| + if (!local_state) { |
| + LOG(ERROR) << "Cannot get local_state for prefs, not initializing volume"; |
| + return; |
| + } |
| + |
| + if (!local_state->FindPreference(prefs::kAudioVolume)) { |
| + local_state->RegisterRealPref(prefs::kAudioVolume, kPrefVolumeNotSet); |
| + local_state->RegisterBooleanPref(prefs::kAudioMute, false); |
| + } |
| + |
| + DCHECK(local_state->FindPreference(prefs::kAudioVolume)); |
| + double pref_volume = local_state->GetReal(prefs::kAudioVolume); |
| + |
| + if (pref_volume != kPrefVolumeNotSet) { |
| + DCHECK(local_state->FindPreference(prefs::kAudioMute)); |
| + bool pref_mute = local_state->GetBoolean(prefs::kAudioMute); |
| + |
| + thread_->message_loop()->PostTask(FROM_HERE, |
| + NewRunnableMethod(this, &AudioMixerAlsa::DoSetVolumeMute, |
| + pref_volume, pref_mute)); |
| + } |
| +} |
| + |
| +void AudioMixerAlsa::SaveVolume(double volume) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + if (!g_browser_process) |
| + return; |
| + |
| + PrefService* local_state = g_browser_process->local_state(); |
| + if (!local_state) { |
| + LOG(ERROR) << "Cannot get local_state to store volume in prefs"; |
| + return; |
| + } |
| + DCHECK(local_state->FindPreference(prefs::kAudioVolume)); |
| + local_state->SetReal(prefs::kAudioVolume, volume); |
| +} |
| + |
| +void AudioMixerAlsa::SaveMute(bool mute) { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + if (!g_browser_process) |
| + return; |
| + |
| + PrefService* local_state = g_browser_process->local_state(); |
| + if (!local_state) { |
|
zhurunz
2011/01/13 00:19:25
Could we add a util function to get local_state so
davejcool
2011/01/13 21:31:14
By using the PrefMember class, I was able to encap
|
| + LOG(ERROR) << "Cannot get local_state to store mute in prefs"; |
| + return; |
| + } |
| + DCHECK(local_state->FindPreference(prefs::kAudioMute)); |
| + local_state->SetBoolean(prefs::kAudioMute, mute); |
| +} |
| + |
| } // namespace chromeos |