Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chromeos / audio / audio_devices_pref_handler_impl.cc
blob17b5681ebce457ca4feffe8a9f1479fa95ee4832
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"
7 #include <algorithm>
9 #include "base/bind.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"
19 namespace {
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
31 // them.
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;
43 } // namespace
45 namespace chromeos {
47 double AudioDevicesPrefHandlerImpl::GetOutputVolumeValue(
48 const AudioDevice* device) {
49 if (!device)
50 return kDefaultOutputVolumePercent;
51 else
52 return GetVolumeGainPrefValue(*device);
55 double AudioDevicesPrefHandlerImpl::GetInputGainValue(
56 const AudioDevice* device) {
57 DCHECK(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,
82 bool mute) {
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);
118 return value;
121 double AudioDevicesPrefHandlerImpl::GetDeviceDefaultOutputVolume(
122 const AudioDevice& device) {
123 if (device.type == AUDIO_TYPE_HDMI)
124 return kDefaultHdmiOutputVolumePercent;
125 else
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);
154 if (mute_prefs)
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);
165 it.Advance();
169 void AudioDevicesPrefHandlerImpl::UpdateDevicesVolumePref() {
170 const base::DictionaryValue* volume_prefs =
171 local_state_->GetDictionary(prefs::kAudioDevicesVolumePercent);
172 if (volume_prefs)
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);
183 DCHECK(success);
184 dict_update->SetDouble(it.key(), volume);
185 it.Advance();
189 void AudioDevicesPrefHandlerImpl::MigrateDeviceMuteSettings(
190 const 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 const 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,
205 observers_,
206 OnAudioPolicyPrefChanged());
209 // static
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
216 // media system.
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