forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Switch Audio Preferences to per device.
Currently Chrome stores one global audio volume pref; if a user switches devices, this value remains the same. Change this so that we remember what volume (and mute setting) a user switched to when on a particular device, so when we switch to that device, we can set the volume/mute setting back to it again. R=brettw@chromium.org, hshi@chromium.org, stevenjb@chromium.org BUG=175798 TEST=Switched between speakers and USB headphones to verify that audio settings were rememebered and switched to correctly. Review URL: https://codereview.chromium.org/14801002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198011 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
rkc@chromium.org
committed
May 2, 2013
1 parent
983efa8
commit 36221c6
Showing
14 changed files
with
369 additions
and
29 deletions.
There are no files selected for viewing
192 changes: 192 additions & 0 deletions
192
chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
// Copyright (c) 2013 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.h" | ||
|
||
#include "base/bind.h" | ||
#include "base/bind_helpers.h" | ||
#include "base/logging.h" | ||
#include "base/prefs/pref_registry_simple.h" | ||
#include "base/prefs/pref_service.h" | ||
#include "base/strings/string_number_conversions.h" | ||
#include "chrome/browser/prefs/scoped_user_pref_update.h" | ||
#include "chrome/common/chrome_notification_types.h" | ||
#include "chrome/common/pref_names.h" | ||
#include "chromeos/audio/cras_audio_handler.h" | ||
|
||
namespace chromeos { | ||
|
||
namespace { | ||
|
||
// Default value for the volume pref, as a percent in the range [0.0, 100.0]. | ||
const double kDefaultVolumePercent = 75.0; | ||
|
||
// Values used for muted preference. | ||
const int kPrefMuteOff = 0; | ||
const int kPrefMuteOn = 1; | ||
|
||
} // namespace | ||
|
||
double AudioDevicesPrefHandlerImpl::GetOutputVolumeValue() { | ||
if (!CrasAudioHandler::IsInitialized()) | ||
return kDefaultVolumePercent; | ||
|
||
UpdateDevicesVolumePref(); | ||
std::string active_device_id = base::Uint64ToString( | ||
CrasAudioHandler::Get()->GetActiveOutputNode()); | ||
if (!device_volume_settings_->HasKey(active_device_id)) | ||
MigrateDeviceVolumeSettings(active_device_id); | ||
double volume = kDefaultVolumePercent; | ||
device_volume_settings_->GetDouble(active_device_id, &volume); | ||
return volume; | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::SetOutputVolumeValue(double volume_percent) { | ||
std::string active_device_id = base::Uint64ToString( | ||
CrasAudioHandler::Get()->GetActiveOutputNode()); | ||
if (volume_percent > 100.0) | ||
volume_percent = 100.0; | ||
if (volume_percent < 0.0) | ||
volume_percent = 0.0; | ||
device_volume_settings_->SetDouble(active_device_id, volume_percent); | ||
SaveDevicesVolumePref(); | ||
} | ||
|
||
bool AudioDevicesPrefHandlerImpl::GetOutputMuteValue() { | ||
if (!CrasAudioHandler::IsInitialized()) | ||
return false; | ||
|
||
UpdateDevicesVolumePref(); | ||
std::string active_device_id = base::Uint64ToString( | ||
CrasAudioHandler::Get()->GetActiveOutputNode()); | ||
if (!device_mute_settings_->HasKey(active_device_id)) | ||
MigrateDeviceMuteSettings(active_device_id); | ||
int mute = kPrefMuteOff; | ||
device_mute_settings_->GetInteger(active_device_id, &mute); | ||
return (mute == kPrefMuteOn); | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::SetOutputMuteValue(bool mute) { | ||
std::string active_device_id = base::Uint64ToString( | ||
CrasAudioHandler::Get()->GetActiveOutputNode()); | ||
device_mute_settings_->SetBoolean(active_device_id, | ||
mute ? kPrefMuteOn : kPrefMuteOff); | ||
SaveDevicesVolumePref(); | ||
} | ||
|
||
bool AudioDevicesPrefHandlerImpl::GetAudioCaptureAllowedValue() { | ||
return local_state_->GetBoolean(prefs::kAudioCaptureAllowed); | ||
} | ||
|
||
bool AudioDevicesPrefHandlerImpl::GetAudioOutputAllowedValue() { | ||
return local_state_->GetBoolean(prefs::kAudioOutputAllowed); | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::AddAudioPrefObserver( | ||
AudioPrefObserver* observer) { | ||
observers_.AddObserver(observer); | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::RemoveAudioPrefObserver( | ||
AudioPrefObserver* observer) { | ||
observers_.RemoveObserver(observer); | ||
} | ||
|
||
AudioDevicesPrefHandlerImpl::AudioDevicesPrefHandlerImpl( | ||
PrefService* local_state) | ||
: device_mute_settings_(new base::DictionaryValue()), | ||
device_volume_settings_(new base::DictionaryValue()), | ||
local_state_(local_state) { | ||
InitializePrefObservers(); | ||
|
||
UpdateDevicesMutePref(); | ||
UpdateDevicesVolumePref(); | ||
} | ||
|
||
AudioDevicesPrefHandlerImpl::~AudioDevicesPrefHandlerImpl() { | ||
}; | ||
|
||
void AudioDevicesPrefHandlerImpl::InitializePrefObservers() { | ||
pref_change_registrar_.Init(local_state_); | ||
base::Closure callback = | ||
base::Bind(&AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange, | ||
base::Unretained(this)); | ||
pref_change_registrar_.Add(prefs::kAudioOutputAllowed, callback); | ||
pref_change_registrar_.Add(prefs::kAudioCaptureAllowed, callback); | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::UpdateDevicesMutePref() { | ||
const base::DictionaryValue* mute_prefs = | ||
local_state_->GetDictionary(prefs::kAudioDevicesMute); | ||
if (mute_prefs) | ||
device_mute_settings_.reset(mute_prefs->DeepCopy()); | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::SaveDevicesMutePref() { | ||
DictionaryPrefUpdate dict_update(local_state_, prefs::kAudioDevicesMute); | ||
base::DictionaryValue::Iterator it(*device_mute_settings_); | ||
while (!it.IsAtEnd()) { | ||
int mute = kPrefMuteOff; | ||
it.value().GetAsInteger(&mute); | ||
dict_update->Set(it.key(), new base::FundamentalValue(mute)); | ||
it.Advance(); | ||
} | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::UpdateDevicesVolumePref() { | ||
const base::DictionaryValue* volume_prefs = | ||
local_state_->GetDictionary(prefs::kAudioDevicesVolumePercent); | ||
if (volume_prefs) | ||
device_volume_settings_.reset(volume_prefs->DeepCopy()); | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::SaveDevicesVolumePref() { | ||
DictionaryPrefUpdate dict_update(local_state_, | ||
prefs::kAudioDevicesVolumePercent); | ||
base::DictionaryValue::Iterator it(*device_volume_settings_); | ||
while (!it.IsAtEnd()) { | ||
double volume = kDefaultVolumePercent; | ||
it.value().GetAsDouble(&volume); | ||
dict_update->Set(it.key(), new base::FundamentalValue(volume)); | ||
it.Advance(); | ||
} | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::MigrateDeviceMuteSettings( | ||
std::string active_device) { | ||
int old_mute = local_state_->GetInteger(prefs::kAudioMute); | ||
device_mute_settings_->SetInteger(active_device, old_mute); | ||
SaveDevicesMutePref(); | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::MigrateDeviceVolumeSettings( | ||
std::string active_device) { | ||
double old_volume = local_state_->GetDouble(prefs::kAudioVolumePercent); | ||
device_volume_settings_->SetDouble(active_device, old_volume); | ||
SaveDevicesVolumePref(); | ||
} | ||
|
||
void AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange() { | ||
FOR_EACH_OBSERVER(AudioPrefObserver, | ||
observers_, | ||
OnAudioPolicyPrefChanged()); | ||
} | ||
|
||
// static | ||
void AudioDevicesPrefHandlerImpl::RegisterPrefs(PrefRegistrySimple* registry) { | ||
registry->RegisterDictionaryPref(prefs::kAudioDevicesVolumePercent); | ||
registry->RegisterDictionaryPref(prefs::kAudioDevicesMute); | ||
|
||
// TODO(jennyz,rkc): Move the rest of the preferences registered by | ||
// AudioPrefHandlerImpl::RegisterPrefs here once we remove the old audio | ||
// handler code. | ||
} | ||
|
||
// static | ||
AudioDevicesPrefHandler* AudioDevicesPrefHandler::Create( | ||
PrefService* local_state) { | ||
return new AudioDevicesPrefHandlerImpl(local_state); | ||
} | ||
|
||
} // namespace chromeos |
74 changes: 74 additions & 0 deletions
74
chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright (c) 2013 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_CHROMEOS_AUDIO_AUDIO_DEVICES_PREF_HANDLER_IMPL_H_ | ||
#define CHROME_BROWSER_CHROMEOS_AUDIO_AUDIO_DEVICES_PREF_HANDLER_IMPL_H_ | ||
|
||
#include "base/observer_list.h" | ||
#include "base/prefs/pref_change_registrar.h" | ||
#include "base/values.h" | ||
#include "chromeos/audio/audio_devices_pref_handler.h" | ||
|
||
class PrefRegistrySimple; | ||
class PrefService; | ||
|
||
namespace chromeos { | ||
|
||
// Class which implements AudioDevicesPrefHandler interface and register audio | ||
// preferences as well. | ||
class AudioDevicesPrefHandlerImpl : public AudioDevicesPrefHandler { | ||
public: | ||
explicit AudioDevicesPrefHandlerImpl(PrefService* local_state); | ||
|
||
// Overridden from AudioDevicesPrefHandler. | ||
virtual double GetOutputVolumeValue() OVERRIDE; | ||
virtual bool GetOutputMuteValue() OVERRIDE; | ||
virtual void SetOutputVolumeValue(double volume_percent) OVERRIDE; | ||
virtual void SetOutputMuteValue(bool mute_on) OVERRIDE; | ||
virtual bool GetAudioCaptureAllowedValue() OVERRIDE; | ||
virtual bool GetAudioOutputAllowedValue() OVERRIDE; | ||
virtual void AddAudioPrefObserver(AudioPrefObserver* observer) OVERRIDE; | ||
virtual void RemoveAudioPrefObserver(AudioPrefObserver* observer) OVERRIDE; | ||
|
||
// Registers volume and mute preferences. | ||
static void RegisterPrefs(PrefRegistrySimple* registry); | ||
|
||
protected: | ||
virtual ~AudioDevicesPrefHandlerImpl(); | ||
|
||
private: | ||
// Initializes the observers for the policy prefs. | ||
void InitializePrefObservers(); | ||
|
||
// Update and save methods for the mute preferences for all devices. | ||
void UpdateDevicesMutePref(); | ||
void SaveDevicesMutePref(); | ||
|
||
// Update and save methods for the volume preferences for all devices. | ||
void UpdateDevicesVolumePref(); | ||
void SaveDevicesVolumePref(); | ||
|
||
// Methods to migrate the mute and volume settings for a device from the | ||
// previous global pref value to the new per device pref value for the | ||
// current active device. If a previous global setting doesn't exist, we'll | ||
// use default values of mute = off and volume = 75%. | ||
void MigrateDeviceMuteSettings(std::string active_device); | ||
void MigrateDeviceVolumeSettings(std::string active_device); | ||
|
||
// Notifies the AudioPrefObserver for audio policy pref changes. | ||
void NotifyAudioPolicyChange(); | ||
|
||
scoped_ptr<base::DictionaryValue> device_mute_settings_; | ||
scoped_ptr<base::DictionaryValue> device_volume_settings_; | ||
|
||
PrefService* local_state_; // not owned | ||
PrefChangeRegistrar pref_change_registrar_; | ||
ObserverList<AudioPrefObserver> observers_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(AudioDevicesPrefHandlerImpl); | ||
}; | ||
|
||
} // namespace chromeos | ||
|
||
#endif // CHROME_BROWSER_CHROMEOS_AUDIO_AUDIO_DEVICES_PREF_HANDLER_IMPL_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.