audio_devices_pref_handler_impl.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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 20namespace { 21 22const double kDefaultOutputVolume = 75.0; 23const double kDefaultHDMIOutputVolume = 100.0; 24 25// Values used for muted preference. 26const int kPrefMuteOff = 0; 27const 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. 36std::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 44namespace chromeos { 45 46double AudioDevicesPrefHandlerImpl::GetOutputVolumeValue( 47 const AudioDevice* device) { 48 if (!device) 49 return kDefaultOutputVolume; 50 else 51 return GetVolumeGainPrefValue(*device); 52} 53 54double AudioDevicesPrefHandlerImpl::GetInputGainValue( 55 const AudioDevice* device) { 56 DCHECK(device); 57 return GetVolumeGainPrefValue(*device); 58} 59 60void AudioDevicesPrefHandlerImpl::SetVolumeGainValue( 61 const AudioDevice& device, double value) { 62 device_volume_settings_->SetDouble(GetDeviceIdString(device), value); 63 64 SaveDevicesVolumePref(); 65} 66 67bool 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 80void AudioDevicesPrefHandlerImpl::SetMuteValue(const AudioDevice& device, 81 bool mute) { 82 device_mute_settings_->SetInteger(GetDeviceIdString(device), 83 mute ? kPrefMuteOn : kPrefMuteOff); 84 SaveDevicesMutePref(); 85} 86 87 88bool AudioDevicesPrefHandlerImpl::GetAudioCaptureAllowedValue() { 89 return local_state_->GetBoolean(prefs::kAudioCaptureAllowed); 90} 91 92bool AudioDevicesPrefHandlerImpl::GetAudioOutputAllowedValue() { 93 return local_state_->GetBoolean(prefs::kAudioOutputAllowed); 94} 95 96void AudioDevicesPrefHandlerImpl::AddAudioPrefObserver( 97 AudioPrefObserver* observer) { 98 observers_.AddObserver(observer); 99} 100 101void AudioDevicesPrefHandlerImpl::RemoveAudioPrefObserver( 102 AudioPrefObserver* observer) { 103 observers_.RemoveObserver(observer); 104} 105 106double 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 123double AudioDevicesPrefHandlerImpl::GetDeviceDefaultOutputVolume( 124 const AudioDevice& device) { 125 if (device.type == AUDIO_TYPE_HDMI) 126 return kDefaultHDMIOutputVolume; 127 else 128 return kDefaultOutputVolume; 129} 130 131AudioDevicesPrefHandlerImpl::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 142AudioDevicesPrefHandlerImpl::~AudioDevicesPrefHandlerImpl() { 143}; 144 145void 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 154void 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 161void 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 172void 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 179void 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 192void 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 199void 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 206void AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange() { 207 FOR_EACH_OBSERVER(AudioPrefObserver, 208 observers_, 209 OnAudioPolicyPrefChanged()); 210} 211 212// static 213void 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 230AudioDevicesPrefHandler* AudioDevicesPrefHandler::Create( 231 PrefService* local_state) { 232 return new AudioDevicesPrefHandlerImpl(local_state); 233} 234 235} // namespace chromeos 236