1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chromeos/audio/audio_devices_pref_handler_impl.h"
10 #include "base/bind_helpers.h"
11 #include "base/logging.h"
12 #include "base/prefs/pref_registry_simple.h"
13 #include "base/prefs/pref_service.h"
14 #include "base/prefs/scoped_user_pref_update.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "chromeos/audio/audio_device.h"
17 #include "chromeos/chromeos_pref_names.h"
21 // Values used for muted preference.
22 const int kPrefMuteOff
= 0;
23 const int kPrefMuteOn
= 1;
25 // Gets the device id string for storing audio preference. The format of
26 // device string is a string consisting of 3 parts.
27 // |device_name| : |integer from lower 32 bit of device id| :
28 // |0(output device) or 1(input device)|
29 // If an audio device has both integrated input and output devices, the first 2
30 // parts of the string could be identical, only the last part will differentiate
32 std::string
GetDeviceIdString(const chromeos::AudioDevice
& device
) {
33 std::string device_id_string
=
34 device
.device_name
+ " : " +
35 base::Uint64ToString(device
.id
& static_cast<uint64
>(0xffffffff)) +
36 " : " + (device
.is_input
? "1" : "0");
37 // Replace any periods from the device id string with a space, since setting
38 // names cannot contain periods.
39 std::replace(device_id_string
.begin(), device_id_string
.end(), '.', ' ');
40 return device_id_string
;
47 double AudioDevicesPrefHandlerImpl::GetOutputVolumeValue(
48 const AudioDevice
* device
) {
50 return kDefaultOutputVolumePercent
;
52 return GetVolumeGainPrefValue(*device
);
55 double AudioDevicesPrefHandlerImpl::GetInputGainValue(
56 const AudioDevice
* device
) {
58 return GetVolumeGainPrefValue(*device
);
61 void AudioDevicesPrefHandlerImpl::SetVolumeGainValue(
62 const AudioDevice
& device
, double value
) {
63 device_volume_settings_
->SetDouble(GetDeviceIdString(device
), value
);
65 SaveDevicesVolumePref();
68 bool AudioDevicesPrefHandlerImpl::GetMuteValue(const AudioDevice
& device
) {
69 UpdateDevicesMutePref();
71 std::string device_id_str
= GetDeviceIdString(device
);
72 if (!device_mute_settings_
->HasKey(device_id_str
))
73 MigrateDeviceMuteSettings(device_id_str
);
75 int mute
= kPrefMuteOff
;
76 device_mute_settings_
->GetInteger(device_id_str
, &mute
);
78 return (mute
== kPrefMuteOn
);
81 void AudioDevicesPrefHandlerImpl::SetMuteValue(const AudioDevice
& device
,
83 device_mute_settings_
->SetInteger(GetDeviceIdString(device
),
84 mute
? kPrefMuteOn
: kPrefMuteOff
);
85 SaveDevicesMutePref();
88 bool AudioDevicesPrefHandlerImpl::GetAudioOutputAllowedValue() {
89 return local_state_
->GetBoolean(prefs::kAudioOutputAllowed
);
92 void AudioDevicesPrefHandlerImpl::AddAudioPrefObserver(
93 AudioPrefObserver
* observer
) {
94 observers_
.AddObserver(observer
);
97 void AudioDevicesPrefHandlerImpl::RemoveAudioPrefObserver(
98 AudioPrefObserver
* observer
) {
99 observers_
.RemoveObserver(observer
);
102 double AudioDevicesPrefHandlerImpl::GetVolumeGainPrefValue(
103 const AudioDevice
& device
) {
104 UpdateDevicesVolumePref();
106 std::string device_id_str
= GetDeviceIdString(device
);
107 if (!device_volume_settings_
->HasKey(device_id_str
))
108 MigrateDeviceVolumeSettings(device_id_str
);
110 // TODO(jennyz, rkc): Return a meaningful input gain default value, when
111 // cras has added support for normalizing input gain range.
112 double value
= device
.is_input
?
113 0.0 : GetDeviceDefaultOutputVolume(device
);
114 // TODO(rkc): The above code is completely ignored since we 'always' have a
115 // default pref value. Fix this. http://crbug.com/442489
116 device_volume_settings_
->GetDouble(device_id_str
, &value
);
121 double AudioDevicesPrefHandlerImpl::GetDeviceDefaultOutputVolume(
122 const AudioDevice
& device
) {
123 if (device
.type
== AUDIO_TYPE_HDMI
)
124 return kDefaultHdmiOutputVolumePercent
;
126 return kDefaultOutputVolumePercent
;
129 AudioDevicesPrefHandlerImpl::AudioDevicesPrefHandlerImpl(
130 PrefService
* local_state
)
131 : device_mute_settings_(new base::DictionaryValue()),
132 device_volume_settings_(new base::DictionaryValue()),
133 local_state_(local_state
) {
134 InitializePrefObservers();
136 UpdateDevicesMutePref();
137 UpdateDevicesVolumePref();
140 AudioDevicesPrefHandlerImpl::~AudioDevicesPrefHandlerImpl() {
143 void AudioDevicesPrefHandlerImpl::InitializePrefObservers() {
144 pref_change_registrar_
.Init(local_state_
);
145 base::Closure callback
=
146 base::Bind(&AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange
,
147 base::Unretained(this));
148 pref_change_registrar_
.Add(prefs::kAudioOutputAllowed
, callback
);
151 void AudioDevicesPrefHandlerImpl::UpdateDevicesMutePref() {
152 const base::DictionaryValue
* mute_prefs
=
153 local_state_
->GetDictionary(prefs::kAudioDevicesMute
);
155 device_mute_settings_
.reset(mute_prefs
->DeepCopy());
158 void AudioDevicesPrefHandlerImpl::SaveDevicesMutePref() {
159 DictionaryPrefUpdate
dict_update(local_state_
, prefs::kAudioDevicesMute
);
160 base::DictionaryValue::Iterator
it(*device_mute_settings_
);
161 while (!it
.IsAtEnd()) {
162 int mute
= kPrefMuteOff
;
163 it
.value().GetAsInteger(&mute
);
164 dict_update
->SetInteger(it
.key(), mute
);
169 void AudioDevicesPrefHandlerImpl::UpdateDevicesVolumePref() {
170 const base::DictionaryValue
* volume_prefs
=
171 local_state_
->GetDictionary(prefs::kAudioDevicesVolumePercent
);
173 device_volume_settings_
.reset(volume_prefs
->DeepCopy());
176 void AudioDevicesPrefHandlerImpl::SaveDevicesVolumePref() {
177 DictionaryPrefUpdate
dict_update(local_state_
,
178 prefs::kAudioDevicesVolumePercent
);
179 base::DictionaryValue::Iterator
it(*device_volume_settings_
);
180 while (!it
.IsAtEnd()) {
181 double volume
= kDefaultOutputVolumePercent
;
182 bool success
= it
.value().GetAsDouble(&volume
);
184 dict_update
->SetDouble(it
.key(), volume
);
189 void AudioDevicesPrefHandlerImpl::MigrateDeviceMuteSettings(
190 std::string active_device
) {
191 int old_mute
= local_state_
->GetInteger(prefs::kAudioMute
);
192 device_mute_settings_
->SetInteger(active_device
, old_mute
);
193 SaveDevicesMutePref();
196 void AudioDevicesPrefHandlerImpl::MigrateDeviceVolumeSettings(
197 std::string active_device
) {
198 double old_volume
= local_state_
->GetDouble(prefs::kAudioVolumePercent
);
199 device_volume_settings_
->SetDouble(active_device
, old_volume
);
200 SaveDevicesVolumePref();
203 void AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange() {
204 FOR_EACH_OBSERVER(AudioPrefObserver
,
206 OnAudioPolicyPrefChanged());
210 void AudioDevicesPrefHandlerImpl::RegisterPrefs(PrefRegistrySimple
* registry
) {
211 registry
->RegisterDictionaryPref(prefs::kAudioDevicesVolumePercent
);
212 registry
->RegisterDictionaryPref(prefs::kAudioDevicesMute
);
214 // Register the prefs backing the audio muting policies.
215 // Policy for audio input is handled by kAudioCaptureAllowed in the Chrome
217 registry
->RegisterBooleanPref(prefs::kAudioOutputAllowed
, true);
219 // Register the legacy audio prefs for migration.
220 registry
->RegisterDoublePref(prefs::kAudioVolumePercent
,
221 kDefaultOutputVolumePercent
);
222 registry
->RegisterIntegerPref(prefs::kAudioMute
, kPrefMuteOff
);
225 } // namespace chromeos