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 16namespace chromeos { 17 18static base::LazyInstance<CrosSettings> g_cros_settings( 19 base::LINKER_INITIALIZED); 20 21CrosSettings* CrosSettings::Get() { 22 // TODO(xiyaun): Use real stuff when underlying libcros is ready. 23 return g_cros_settings.Pointer(); 24} 25 26bool CrosSettings::IsCrosSettings(const std::string& path) { 27 return StartsWithASCII(path, kCrosSettingsPrefix, true); 28} 29 30void 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 47void 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 56void CrosSettings::SetBoolean(const std::string& path, bool in_value) { 57 DCHECK(CalledOnValidThread()); 58 Set(path, Value::CreateBooleanValue(in_value)); 59} 60 61void CrosSettings::SetInteger(const std::string& path, int in_value) { 62 DCHECK(CalledOnValidThread()); 63 Set(path, Value::CreateIntegerValue(in_value)); 64} 65 66void CrosSettings::SetDouble(const std::string& path, double in_value) { 67 DCHECK(CalledOnValidThread()); 68 Set(path, Value::CreateDoubleValue(in_value)); 69} 70 71void CrosSettings::SetString(const std::string& path, 72 const std::string& in_value) { 73 DCHECK(CalledOnValidThread()); 74 Set(path, Value::CreateStringValue(in_value)); 75} 76 77bool CrosSettings::AddSettingsProvider(CrosSettingsProvider* provider) { 78 DCHECK(CalledOnValidThread()); 79 providers_.push_back(provider); 80 return true; 81} 82 83bool 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 94void 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 130void 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 144CrosSettingsProvider* 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 154bool 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 164bool 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 174bool 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 184bool 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 194bool 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 204CrosSettings::CrosSettings() { 205} 206 207CrosSettings::~CrosSettings() { 208 DCHECK(providers_.empty()); 209} 210 211} // namespace chromeos 212