blob: 4e72de6c1ca6ac4bf2e597d3330e5a502170583e [file] [log] [blame]
[email protected]36221c692013-05-02 23:45:471// 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.
4
jamescook9439c7392014-12-18 01:47:255#include "chromeos/audio/audio_devices_pref_handler_impl.h"
[email protected]36221c692013-05-02 23:45:476
[email protected]029a00c2013-05-07 00:44:587#include <algorithm>
8
[email protected]36221c692013-05-02 23:45:479#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"
[email protected]9eec53fe2013-10-30 20:21:1714#include "base/prefs/scoped_user_pref_update.h"
[email protected]36221c692013-05-02 23:45:4715#include "base/strings/string_number_conversions.h"
[email protected]6fda9fb82013-06-20 21:57:3816#include "chromeos/audio/audio_device.h"
jamescook9439c7392014-12-18 01:47:2517#include "chromeos/chromeos_pref_names.h"
[email protected]36221c692013-05-02 23:45:4718
[email protected]6fda9fb82013-06-20 21:57:3819namespace {
20
[email protected]140a31452013-09-09 18:54:3721// Values used for muted preference.
22const int kPrefMuteOff = 0;
23const int kPrefMuteOn = 1;
24
[email protected]6e5feea2013-09-19 05:02:1125// 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.
[email protected]6fda9fb82013-06-20 21:57:3832std::string GetDeviceIdString(const chromeos::AudioDevice& device) {
rkce0a1ab0b2014-12-15 23:45:2333 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;
[email protected]6fda9fb82013-06-20 21:57:3841}
42
[email protected]140a31452013-09-09 18:54:3743} // namespace
[email protected]6fda9fb82013-06-20 21:57:3844
[email protected]36221c692013-05-02 23:45:4745namespace chromeos {
46
[email protected]140a31452013-09-09 18:54:3747double AudioDevicesPrefHandlerImpl::GetOutputVolumeValue(
48 const AudioDevice* device) {
49 if (!device)
jamescook150158512014-12-19 02:55:0050 return kDefaultOutputVolumePercent;
[email protected]140a31452013-09-09 18:54:3751 else
52 return GetVolumeGainPrefValue(*device);
53}
[email protected]029a00c2013-05-07 00:44:5854
[email protected]140a31452013-09-09 18:54:3755double AudioDevicesPrefHandlerImpl::GetInputGainValue(
56 const AudioDevice* device) {
57 DCHECK(device);
58 return GetVolumeGainPrefValue(*device);
[email protected]36221c692013-05-02 23:45:4759}
60
[email protected]029a00c2013-05-07 00:44:5861void AudioDevicesPrefHandlerImpl::SetVolumeGainValue(
[email protected]6fda9fb82013-06-20 21:57:3862 const AudioDevice& device, double value) {
[email protected]6fda9fb82013-06-20 21:57:3863 device_volume_settings_->SetDouble(GetDeviceIdString(device), value);
[email protected]029a00c2013-05-07 00:44:5864
[email protected]36221c692013-05-02 23:45:4765 SaveDevicesVolumePref();
66}
67
[email protected]6fda9fb82013-06-20 21:57:3868bool AudioDevicesPrefHandlerImpl::GetMuteValue(const AudioDevice& device) {
[email protected]bf9fc822013-05-10 10:55:5769 UpdateDevicesMutePref();
[email protected]029a00c2013-05-07 00:44:5870
[email protected]6fda9fb82013-06-20 21:57:3871 std::string device_id_str = GetDeviceIdString(device);
[email protected]029a00c2013-05-07 00:44:5872 if (!device_mute_settings_->HasKey(device_id_str))
73 MigrateDeviceMuteSettings(device_id_str);
74
[email protected]36221c692013-05-02 23:45:4775 int mute = kPrefMuteOff;
[email protected]029a00c2013-05-07 00:44:5876 device_mute_settings_->GetInteger(device_id_str, &mute);
77
[email protected]36221c692013-05-02 23:45:4778 return (mute == kPrefMuteOn);
79}
80
[email protected]6fda9fb82013-06-20 21:57:3881void AudioDevicesPrefHandlerImpl::SetMuteValue(const AudioDevice& device,
[email protected]029a00c2013-05-07 00:44:5882 bool mute) {
[email protected]6fda9fb82013-06-20 21:57:3883 device_mute_settings_->SetInteger(GetDeviceIdString(device),
[email protected]029a00c2013-05-07 00:44:5884 mute ? kPrefMuteOn : kPrefMuteOff);
[email protected]bf9fc822013-05-10 10:55:5785 SaveDevicesMutePref();
[email protected]36221c692013-05-02 23:45:4786}
87
[email protected]36221c692013-05-02 23:45:4788bool AudioDevicesPrefHandlerImpl::GetAudioOutputAllowedValue() {
89 return local_state_->GetBoolean(prefs::kAudioOutputAllowed);
90}
91
92void AudioDevicesPrefHandlerImpl::AddAudioPrefObserver(
93 AudioPrefObserver* observer) {
94 observers_.AddObserver(observer);
95}
96
97void AudioDevicesPrefHandlerImpl::RemoveAudioPrefObserver(
98 AudioPrefObserver* observer) {
99 observers_.RemoveObserver(observer);
100}
101
[email protected]140a31452013-09-09 18:54:37102double AudioDevicesPrefHandlerImpl::GetVolumeGainPrefValue(
103 const AudioDevice& device) {
104 UpdateDevicesVolumePref();
105
106 std::string device_id_str = GetDeviceIdString(device);
107 if (!device_volume_settings_->HasKey(device_id_str))
108 MigrateDeviceVolumeSettings(device_id_str);
109
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);
rkce0a1ab0b2014-12-15 23:45:23114 // TODO(rkc): The above code is completely ignored since we 'always' have a
115 // default pref value. Fix this. http://crbug.com/442489
[email protected]140a31452013-09-09 18:54:37116 device_volume_settings_->GetDouble(device_id_str, &value);
117
118 return value;
119}
120
121double AudioDevicesPrefHandlerImpl::GetDeviceDefaultOutputVolume(
122 const AudioDevice& device) {
123 if (device.type == AUDIO_TYPE_HDMI)
jamescook150158512014-12-19 02:55:00124 return kDefaultHdmiOutputVolumePercent;
[email protected]140a31452013-09-09 18:54:37125 else
jamescook150158512014-12-19 02:55:00126 return kDefaultOutputVolumePercent;
[email protected]140a31452013-09-09 18:54:37127}
128
[email protected]36221c692013-05-02 23:45:47129AudioDevicesPrefHandlerImpl::AudioDevicesPrefHandlerImpl(
jamescook928c5e82015-01-07 20:47:18130 PrefService* local_state)
[email protected]36221c692013-05-02 23:45:47131 : device_mute_settings_(new base::DictionaryValue()),
132 device_volume_settings_(new base::DictionaryValue()),
jamescook928c5e82015-01-07 20:47:18133 local_state_(local_state) {
[email protected]36221c692013-05-02 23:45:47134 InitializePrefObservers();
135
136 UpdateDevicesMutePref();
137 UpdateDevicesVolumePref();
138}
139
140AudioDevicesPrefHandlerImpl::~AudioDevicesPrefHandlerImpl() {
rkce0a1ab0b2014-12-15 23:45:23141}
[email protected]36221c692013-05-02 23:45:47142
143void 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);
[email protected]36221c692013-05-02 23:45:47149}
150
151void 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());
156}
157
158void 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);
[email protected]bf9fc822013-05-10 10:55:57164 dict_update->SetInteger(it.key(), mute);
[email protected]36221c692013-05-02 23:45:47165 it.Advance();
166 }
167}
168
169void 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());
174}
175
176void AudioDevicesPrefHandlerImpl::SaveDevicesVolumePref() {
177 DictionaryPrefUpdate dict_update(local_state_,
178 prefs::kAudioDevicesVolumePercent);
179 base::DictionaryValue::Iterator it(*device_volume_settings_);
180 while (!it.IsAtEnd()) {
jamescook150158512014-12-19 02:55:00181 double volume = kDefaultOutputVolumePercent;
[email protected]140a31452013-09-09 18:54:37182 bool success = it.value().GetAsDouble(&volume);
183 DCHECK(success);
[email protected]bf9fc822013-05-10 10:55:57184 dict_update->SetDouble(it.key(), volume);
[email protected]36221c692013-05-02 23:45:47185 it.Advance();
186 }
187}
188
189void 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();
194}
195
196void 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();
201}
202
203void AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange() {
204 FOR_EACH_OBSERVER(AudioPrefObserver,
205 observers_,
206 OnAudioPolicyPrefChanged());
207}
208
209// static
jamescook928c5e82015-01-07 20:47:18210void AudioDevicesPrefHandlerImpl::RegisterPrefs(PrefRegistrySimple* registry) {
[email protected]36221c692013-05-02 23:45:47211 registry->RegisterDictionaryPref(prefs::kAudioDevicesVolumePercent);
212 registry->RegisterDictionaryPref(prefs::kAudioDevicesMute);
213
[email protected]82578f92013-08-01 20:14:40214 // Register the prefs backing the audio muting policies.
jamescook928c5e82015-01-07 20:47:18215 // Policy for audio input is handled by kAudioCaptureAllowed in the Chrome
216 // media system.
[email protected]82578f92013-08-01 20:14:40217 registry->RegisterBooleanPref(prefs::kAudioOutputAllowed, true);
jamescook9439c7392014-12-18 01:47:25218
[email protected]82578f92013-08-01 20:14:40219 // Register the legacy audio prefs for migration.
220 registry->RegisterDoublePref(prefs::kAudioVolumePercent,
jamescook150158512014-12-19 02:55:00221 kDefaultOutputVolumePercent);
[email protected]82578f92013-08-01 20:14:40222 registry->RegisterIntegerPref(prefs::kAudioMute, kPrefMuteOff);
[email protected]36221c692013-05-02 23:45:47223}
224
[email protected]36221c692013-05-02 23:45:47225} // namespace chromeos