Home | History | Annotate | Download | only in audio
      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.
     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 
     46 double AudioDevicesPrefHandlerImpl::GetOutputVolumeValue(
     47     const AudioDevice* device) {
     48   if (!device)
     49     return kDefaultOutputVolume;
     50   else
     51     return GetVolumeGainPrefValue(*device);
     52 }
     53 
     54 double AudioDevicesPrefHandlerImpl::GetInputGainValue(
     55     const AudioDevice* device) {
     56   DCHECK(device);
     57   return GetVolumeGainPrefValue(*device);
     58 }
     59 
     60 void AudioDevicesPrefHandlerImpl::SetVolumeGainValue(
     61     const AudioDevice& device, double value) {
     62   device_volume_settings_->SetDouble(GetDeviceIdString(device), value);
     63 
     64   SaveDevicesVolumePref();
     65 }
     66 
     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 
     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 
     88 bool AudioDevicesPrefHandlerImpl::GetAudioCaptureAllowedValue() {
     89   return local_state_->GetBoolean(prefs::kAudioCaptureAllowed);
     90 }
     91 
     92 bool AudioDevicesPrefHandlerImpl::GetAudioOutputAllowedValue() {
     93   return local_state_->GetBoolean(prefs::kAudioOutputAllowed);
     94 }
     95 
     96 void AudioDevicesPrefHandlerImpl::AddAudioPrefObserver(
     97     AudioPrefObserver* observer) {
     98   observers_.AddObserver(observer);
     99 }
    100 
    101 void AudioDevicesPrefHandlerImpl::RemoveAudioPrefObserver(
    102     AudioPrefObserver* observer) {
    103   observers_.RemoveObserver(observer);
    104 }
    105 
    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 
    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 
    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 
    142 AudioDevicesPrefHandlerImpl::~AudioDevicesPrefHandlerImpl() {
    143 };
    144 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    206 void AudioDevicesPrefHandlerImpl::NotifyAudioPolicyChange() {
    207   FOR_EACH_OBSERVER(AudioPrefObserver,
    208                     observers_,
    209                     OnAudioPolicyPrefChanged());
    210 }
    211 
    212 // static
    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
    230 AudioDevicesPrefHandler* AudioDevicesPrefHandler::Create(
    231     PrefService* local_state) {
    232   return new AudioDevicesPrefHandlerImpl(local_state);
    233 }
    234 
    235 }  // namespace chromeos
    236