• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/chromeos/audio/audio_devices_pref_handler_impl.h"
6 
7 #include <algorithm>
8 
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 "chrome/browser/chrome_notification_types.h"
17 #include "chrome/common/pref_names.h"
18 #include "chromeos/audio/audio_device.h"
19 
20 namespace {
21 
22 const double kDefaultOutputVolume = 75.0;
23 const double kDefaultHDMIOutputVolume = 100.0;
24 
25 // Values used for muted preference.
26 const int kPrefMuteOff = 0;
27 const int kPrefMuteOn = 1;
28 
29 // Gets the device id string for storing audio preference. The format of
30 // device string is a string consisting of 3 parts.
31 // |device_name| : |integer from lower 32 bit of device id| :
32 // |0(output device) or 1(input device)|
33 // If an audio device has both integrated input and output devices, the first 2
34 // parts of the string could be identical, only the last part will differentiate
35 // them.
GetDeviceIdString(const chromeos::AudioDevice & device)36 std::string GetDeviceIdString(const chromeos::AudioDevice& device) {
37   return device.device_name + " : " +
38          base::Uint64ToString(device.id & static_cast<uint64>(0xffffffff)) +
39          " : " + (device.is_input ? "1" : "0");
40 }
41 
42 }  // namespace
43 
44 namespace chromeos {
45 
GetOutputVolumeValue(const AudioDevice * device)46 double AudioDevicesPrefHandlerImpl::GetOutputVolumeValue(
47     const AudioDevice* device) {
48   if (!device)
49     return kDefaultOutputVolume;
50   else
51     return GetVolumeGainPrefValue(*device);
52 }
53 
GetInputGainValue(const AudioDevice * device)54 double AudioDevicesPrefHandlerImpl::GetInputGainValue(
55     const AudioDevice* device) {
56   DCHECK(device);
57   return GetVolumeGainPrefValue(*device);
58 }
59 
SetVolumeGainValue(const AudioDevice & device,double value)60 void AudioDevicesPrefHandlerImpl::SetVolumeGainValue(
61     const AudioDevice& device, double value) {
62   device_volume_settings_->SetDouble(GetDeviceIdString(device), value);
63 
64   SaveDevicesVolumePref();
65 }
66 
GetMuteValue(const AudioDevice & device)67 bool AudioDevicesPrefHandlerImpl::GetMuteValue(const AudioDevice& device) {
68   UpdateDevicesMutePref();
69 
70   std::string device_id_str = GetDeviceIdString(device);
71   if (!device_mute_settings_->HasKey(device_id_str))
72     MigrateDeviceMuteSettings(device_id_str);
73 
74   int mute = kPrefMuteOff;
75   device_mute_settings_->GetInteger(device_id_str, &mute);
76 
77   return (mute == kPrefMuteOn);
78 }
79 
SetMuteValue(const AudioDevice & device,bool mute)80 void AudioDevicesPrefHandlerImpl::SetMuteValue(const AudioDevice& device,
81                                                bool mute) {
82   device_mute_settings_->SetInteger(GetDeviceIdString(device),
83                                     mute ? kPrefMuteOn : kPrefMuteOff);
84   SaveDevicesMutePref();
85 }
86 
87 
GetAudioCaptureAllowedValue()88 bool AudioDevicesPrefHandlerImpl::GetAudioCaptureAllowedValue() {
89   return local_state_->GetBoolean(prefs::kAudioCaptureAllowed);
90 }
91 
GetAudioOutputAllowedValue()92 bool AudioDevicesPrefHandlerImpl::GetAudioOutputAllowedValue() {
93   return local_state_->GetBoolean(prefs::kAudioOutputAllowed);
94 }
95 
AddAudioPrefObserver(AudioPrefObserver * observer)96 void AudioDevicesPrefHandlerImpl::AddAudioPrefObserver(
97     AudioPrefObserver* observer) {
98   observers_.AddObserver(observer);
99 }
100 
RemoveAudioPrefObserver(AudioPrefObserver * observer)101 void AudioDevicesPrefHandlerImpl::RemoveAudioPrefObserver(
102     AudioPrefObserver* observer) {
103   observers_.RemoveObserver(observer);
104 }
105 
GetVolumeGainPrefValue(const AudioDevice & device)106 double AudioDevicesPrefHandlerImpl::GetVolumeGainPrefValue(
107     const AudioDevice& device) {
108   UpdateDevicesVolumePref();
109 
110   std::string device_id_str = GetDeviceIdString(device);
111   if (!device_volume_settings_->HasKey(device_id_str))
112     MigrateDeviceVolumeSettings(device_id_str);
113 
114   // TODO(jennyz, rkc): Return a meaningful input gain default value, when
115   // cras has added support for normalizing input gain range.
116   double value = device.is_input ?
117       0.0 : GetDeviceDefaultOutputVolume(device);
118   device_volume_settings_->GetDouble(device_id_str, &value);
119 
120   return value;
121 }
122 
GetDeviceDefaultOutputVolume(const AudioDevice & device)123 double AudioDevicesPrefHandlerImpl::GetDeviceDefaultOutputVolume(
124     const AudioDevice& device) {
125   if (device.type == AUDIO_TYPE_HDMI)
126     return kDefaultHDMIOutputVolume;
127   else
128     return kDefaultOutputVolume;
129 }
130 
AudioDevicesPrefHandlerImpl(PrefService * local_state)131 AudioDevicesPrefHandlerImpl::AudioDevicesPrefHandlerImpl(
132     PrefService* local_state)
133     : device_mute_settings_(new base::DictionaryValue()),
134       device_volume_settings_(new base::DictionaryValue()),
135       local_state_(local_state) {
136   InitializePrefObservers();
137 
138   UpdateDevicesMutePref();
139   UpdateDevicesVolumePref();
140 }
141 
~AudioDevicesPrefHandlerImpl()142 AudioDevicesPrefHandlerImpl::~AudioDevicesPrefHandlerImpl() {
143 };
144 
InitializePrefObservers()145 void AudioDevicesPrefHandlerImpl::InitializePrefObservers() {
146   pref_change_registrar_.Init(local_state_);
147   base::Closure callback =
148       base::Bind(&AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange,
149                  base::Unretained(this));
150   pref_change_registrar_.Add(prefs::kAudioOutputAllowed, callback);
151   pref_change_registrar_.Add(prefs::kAudioCaptureAllowed, callback);
152 }
153 
UpdateDevicesMutePref()154 void AudioDevicesPrefHandlerImpl::UpdateDevicesMutePref() {
155   const base::DictionaryValue* mute_prefs =
156       local_state_->GetDictionary(prefs::kAudioDevicesMute);
157   if (mute_prefs)
158     device_mute_settings_.reset(mute_prefs->DeepCopy());
159 }
160 
SaveDevicesMutePref()161 void AudioDevicesPrefHandlerImpl::SaveDevicesMutePref() {
162   DictionaryPrefUpdate dict_update(local_state_, prefs::kAudioDevicesMute);
163   base::DictionaryValue::Iterator it(*device_mute_settings_);
164   while (!it.IsAtEnd()) {
165     int mute = kPrefMuteOff;
166     it.value().GetAsInteger(&mute);
167     dict_update->SetInteger(it.key(), mute);
168     it.Advance();
169   }
170 }
171 
UpdateDevicesVolumePref()172 void AudioDevicesPrefHandlerImpl::UpdateDevicesVolumePref() {
173   const base::DictionaryValue* volume_prefs =
174       local_state_->GetDictionary(prefs::kAudioDevicesVolumePercent);
175   if (volume_prefs)
176     device_volume_settings_.reset(volume_prefs->DeepCopy());
177 }
178 
SaveDevicesVolumePref()179 void AudioDevicesPrefHandlerImpl::SaveDevicesVolumePref() {
180   DictionaryPrefUpdate dict_update(local_state_,
181                                    prefs::kAudioDevicesVolumePercent);
182   base::DictionaryValue::Iterator it(*device_volume_settings_);
183   while (!it.IsAtEnd()) {
184     double volume = kDefaultOutputVolume;
185     bool success = it.value().GetAsDouble(&volume);
186     DCHECK(success);
187     dict_update->SetDouble(it.key(), volume);
188     it.Advance();
189   }
190 }
191 
MigrateDeviceMuteSettings(std::string active_device)192 void AudioDevicesPrefHandlerImpl::MigrateDeviceMuteSettings(
193     std::string active_device) {
194   int old_mute = local_state_->GetInteger(prefs::kAudioMute);
195   device_mute_settings_->SetInteger(active_device, old_mute);
196   SaveDevicesMutePref();
197 }
198 
MigrateDeviceVolumeSettings(std::string active_device)199 void AudioDevicesPrefHandlerImpl::MigrateDeviceVolumeSettings(
200     std::string active_device) {
201   double old_volume = local_state_->GetDouble(prefs::kAudioVolumePercent);
202   device_volume_settings_->SetDouble(active_device, old_volume);
203   SaveDevicesVolumePref();
204 }
205 
NotifyAudioPolicyChange()206 void AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange() {
207   FOR_EACH_OBSERVER(AudioPrefObserver,
208                     observers_,
209                     OnAudioPolicyPrefChanged());
210 }
211 
212 // static
RegisterPrefs(PrefRegistrySimple * registry)213 void AudioDevicesPrefHandlerImpl::RegisterPrefs(PrefRegistrySimple* registry) {
214   registry->RegisterDictionaryPref(prefs::kAudioDevicesVolumePercent);
215   registry->RegisterDictionaryPref(prefs::kAudioDevicesMute);
216 
217   // Register the prefs backing the audio muting policies.
218   registry->RegisterBooleanPref(prefs::kAudioOutputAllowed, true);
219   // This pref has moved to the media subsystem but we should verify it is there
220   // before we use it.
221   registry->RegisterBooleanPref(::prefs::kAudioCaptureAllowed, true);
222 
223   // Register the legacy audio prefs for migration.
224   registry->RegisterDoublePref(prefs::kAudioVolumePercent,
225                                kDefaultOutputVolume);
226   registry->RegisterIntegerPref(prefs::kAudioMute, kPrefMuteOff);
227 }
228 
229 // static
Create(PrefService * local_state)230 AudioDevicesPrefHandler* AudioDevicesPrefHandler::Create(
231     PrefService* local_state) {
232   return new AudioDevicesPrefHandlerImpl(local_state);
233 }
234 
235 }  // namespace chromeos
236