Home | History | Annotate | Download | only in chromeos
      1 // Copyright (c) 2011 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/cros_settings.h"
      6 
      7 #include "base/lazy_instance.h"
      8 #include "base/string_util.h"
      9 #include "base/values.h"
     10 #include "chrome/browser/chromeos/cros_settings_provider.h"
     11 #include "chrome/browser/chromeos/user_cros_settings_provider.h"
     12 #include "content/common/notification_details.h"
     13 #include "content/common/notification_source.h"
     14 #include "content/common/notification_type.h"
     15 
     16 namespace chromeos {
     17 
     18 static base::LazyInstance<CrosSettings> g_cros_settings(
     19     base::LINKER_INITIALIZED);
     20 
     21 CrosSettings* CrosSettings::Get() {
     22   // TODO(xiyaun): Use real stuff when underlying libcros is ready.
     23   return g_cros_settings.Pointer();
     24 }
     25 
     26 bool CrosSettings::IsCrosSettings(const std::string& path) {
     27   return StartsWithASCII(path, kCrosSettingsPrefix, true);
     28 }
     29 
     30 void CrosSettings::FireObservers(const char* path) {
     31   DCHECK(CalledOnValidThread());
     32   std::string path_str(path);
     33   SettingsObserverMap::iterator observer_iterator =
     34       settings_observers_.find(path_str);
     35   if (observer_iterator == settings_observers_.end())
     36     return;
     37 
     38   NotificationObserverList::Iterator it(*(observer_iterator->second));
     39   NotificationObserver* observer;
     40   while ((observer = it.GetNext()) != NULL) {
     41     observer->Observe(NotificationType::SYSTEM_SETTING_CHANGED,
     42                       Source<CrosSettings>(this),
     43                       Details<std::string>(&path_str));
     44   }
     45 }
     46 
     47 void CrosSettings::Set(const std::string& path, Value* in_value) {
     48   DCHECK(CalledOnValidThread());
     49   CrosSettingsProvider* provider;
     50   provider = GetProvider(path);
     51   if (provider) {
     52     provider->Set(path, in_value);
     53   }
     54 }
     55 
     56 void CrosSettings::SetBoolean(const std::string& path, bool in_value) {
     57   DCHECK(CalledOnValidThread());
     58   Set(path, Value::CreateBooleanValue(in_value));
     59 }
     60 
     61 void CrosSettings::SetInteger(const std::string& path, int in_value) {
     62   DCHECK(CalledOnValidThread());
     63   Set(path, Value::CreateIntegerValue(in_value));
     64 }
     65 
     66 void CrosSettings::SetDouble(const std::string& path, double in_value) {
     67   DCHECK(CalledOnValidThread());
     68   Set(path, Value::CreateDoubleValue(in_value));
     69 }
     70 
     71 void CrosSettings::SetString(const std::string& path,
     72                              const std::string& in_value) {
     73   DCHECK(CalledOnValidThread());
     74   Set(path, Value::CreateStringValue(in_value));
     75 }
     76 
     77 bool CrosSettings::AddSettingsProvider(CrosSettingsProvider* provider) {
     78   DCHECK(CalledOnValidThread());
     79   providers_.push_back(provider);
     80   return true;
     81 }
     82 
     83 bool CrosSettings::RemoveSettingsProvider(CrosSettingsProvider* provider) {
     84   DCHECK(CalledOnValidThread());
     85   std::vector<CrosSettingsProvider*>::iterator it =
     86       std::find(providers_.begin(), providers_.end(), provider);
     87   if (it != providers_.end()) {
     88     providers_.erase(it);
     89     return true;
     90   }
     91   return false;
     92 }
     93 
     94 void CrosSettings::AddSettingsObserver(const char* path,
     95                                        NotificationObserver* obs) {
     96   DCHECK(path);
     97   DCHECK(obs);
     98   DCHECK(CalledOnValidThread());
     99 
    100   if (!GetProvider(std::string(path))) {
    101     NOTREACHED() << "Trying to add an observer for an unregistered setting: "
    102         << path;
    103     return;
    104   }
    105 
    106   // Get the settings observer list associated with the path.
    107   NotificationObserverList* observer_list = NULL;
    108   SettingsObserverMap::iterator observer_iterator =
    109       settings_observers_.find(path);
    110   if (observer_iterator == settings_observers_.end()) {
    111     observer_list = new NotificationObserverList;
    112     settings_observers_[path] = observer_list;
    113   } else {
    114     observer_list = observer_iterator->second;
    115   }
    116 
    117   // Verify that this observer doesn't already exist.
    118   NotificationObserverList::Iterator it(*observer_list);
    119   NotificationObserver* existing_obs;
    120   while ((existing_obs = it.GetNext()) != NULL) {
    121     DCHECK(existing_obs != obs) << path << " observer already registered";
    122     if (existing_obs == obs)
    123       return;
    124   }
    125 
    126   // Ok, safe to add the pref observer.
    127   observer_list->AddObserver(obs);
    128 }
    129 
    130 void CrosSettings::RemoveSettingsObserver(const char* path,
    131                                           NotificationObserver* obs) {
    132   DCHECK(CalledOnValidThread());
    133 
    134   SettingsObserverMap::iterator observer_iterator =
    135       settings_observers_.find(path);
    136   if (observer_iterator == settings_observers_.end()) {
    137     return;
    138   }
    139 
    140   NotificationObserverList* observer_list = observer_iterator->second;
    141   observer_list->RemoveObserver(obs);
    142 }
    143 
    144 CrosSettingsProvider* CrosSettings::GetProvider(
    145     const std::string& path) const {
    146   for (size_t i = 0; i < providers_.size(); ++i) {
    147     if (providers_[i]->HandlesSetting(path)) {
    148       return providers_[i];
    149     }
    150   }
    151   return NULL;
    152 }
    153 
    154 bool CrosSettings::Get(const std::string& path, Value** out_value) const {
    155   DCHECK(CalledOnValidThread());
    156   CrosSettingsProvider* provider;
    157   provider = GetProvider(path);
    158   if (provider) {
    159     return provider->Get(path, out_value);
    160   }
    161   return false;
    162 }
    163 
    164 bool CrosSettings::GetBoolean(const std::string& path,
    165                               bool* bool_value) const {
    166   DCHECK(CalledOnValidThread());
    167   Value* value;
    168   if (!Get(path, &value))
    169     return false;
    170 
    171   return value->GetAsBoolean(bool_value);
    172 }
    173 
    174 bool CrosSettings::GetInteger(const std::string& path,
    175                               int* out_value) const {
    176   DCHECK(CalledOnValidThread());
    177   Value* value;
    178   if (!Get(path, &value))
    179     return false;
    180 
    181   return value->GetAsInteger(out_value);
    182 }
    183 
    184 bool CrosSettings::GetDouble(const std::string& path,
    185                              double* out_value) const {
    186   DCHECK(CalledOnValidThread());
    187   Value* value;
    188   if (!Get(path, &value))
    189     return false;
    190 
    191   return value->GetAsDouble(out_value);
    192 }
    193 
    194 bool CrosSettings::GetString(const std::string& path,
    195                              std::string* out_value) const {
    196   DCHECK(CalledOnValidThread());
    197   Value* value;
    198   if (!Get(path, &value))
    199     return false;
    200 
    201   return value->GetAsString(out_value);
    202 }
    203 
    204 CrosSettings::CrosSettings() {
    205 }
    206 
    207 CrosSettings::~CrosSettings() {
    208   DCHECK(providers_.empty());
    209 }
    210 
    211 }  // namespace chromeos
    212