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
Get()21 CrosSettings* CrosSettings::Get() {
22 // TODO(xiyaun): Use real stuff when underlying libcros is ready.
23 return g_cros_settings.Pointer();
24 }
25
IsCrosSettings(const std::string & path)26 bool CrosSettings::IsCrosSettings(const std::string& path) {
27 return StartsWithASCII(path, kCrosSettingsPrefix, true);
28 }
29
FireObservers(const char * path)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
Set(const std::string & path,Value * in_value)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
SetBoolean(const std::string & path,bool in_value)56 void CrosSettings::SetBoolean(const std::string& path, bool in_value) {
57 DCHECK(CalledOnValidThread());
58 Set(path, Value::CreateBooleanValue(in_value));
59 }
60
SetInteger(const std::string & path,int in_value)61 void CrosSettings::SetInteger(const std::string& path, int in_value) {
62 DCHECK(CalledOnValidThread());
63 Set(path, Value::CreateIntegerValue(in_value));
64 }
65
SetDouble(const std::string & path,double in_value)66 void CrosSettings::SetDouble(const std::string& path, double in_value) {
67 DCHECK(CalledOnValidThread());
68 Set(path, Value::CreateDoubleValue(in_value));
69 }
70
SetString(const std::string & path,const std::string & in_value)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
AddSettingsProvider(CrosSettingsProvider * provider)77 bool CrosSettings::AddSettingsProvider(CrosSettingsProvider* provider) {
78 DCHECK(CalledOnValidThread());
79 providers_.push_back(provider);
80 return true;
81 }
82
RemoveSettingsProvider(CrosSettingsProvider * provider)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
AddSettingsObserver(const char * path,NotificationObserver * obs)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
RemoveSettingsObserver(const char * path,NotificationObserver * obs)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
GetProvider(const std::string & path) const144 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
Get(const std::string & path,Value ** out_value) const154 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
GetBoolean(const std::string & path,bool * bool_value) const164 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
GetInteger(const std::string & path,int * out_value) const174 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
GetDouble(const std::string & path,double * out_value) const184 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
GetString(const std::string & path,std::string * out_value) const194 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
CrosSettings()204 CrosSettings::CrosSettings() {
205 }
206
~CrosSettings()207 CrosSettings::~CrosSettings() {
208 DCHECK(providers_.empty());
209 }
210
211 } // namespace chromeos
212