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