OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/prefs/pref_value_store.h" | 5 #include "chrome/browser/prefs/pref_value_store.h" |
6 | 6 |
7 #include "chrome/browser/browser_thread.h" | 7 #include "chrome/browser/browser_thread.h" |
8 #include "chrome/browser/extensions/extension_pref_store.h" | 8 #include "chrome/browser/prefs/pref_notifier.h" |
9 #include "chrome/browser/policy/configuration_policy_pref_store.h" | 9 #include "chrome/browser/policy/configuration_policy_pref_store.h" |
10 #include "chrome/browser/prefs/command_line_pref_store.h" | |
11 #include "chrome/browser/prefs/default_pref_store.h" | |
12 #include "chrome/common/json_pref_store.h" | |
13 #include "chrome/common/notification_service.h" | 10 #include "chrome/common/notification_service.h" |
14 | 11 |
15 namespace { | 12 PrefValueStore::PrefStoreKeeper::PrefStoreKeeper() |
16 | 13 : pref_value_store_(NULL), |
17 // Returns true if the actual value is a valid type for the expected type when | 14 type_(PrefValueStore::INVALID_STORE) { |
18 // found in the given store. | |
19 bool IsValidType(Value::ValueType expected, Value::ValueType actual, | |
20 PrefNotifier::PrefStoreType store) { | |
21 if (expected == actual) | |
22 return true; | |
23 | |
24 // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only | |
25 // in the default pref store. | |
26 if (store == PrefNotifier::DEFAULT_STORE && | |
27 actual == Value::TYPE_NULL && | |
28 (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) { | |
29 return true; | |
30 } | |
31 return false; | |
32 } | 15 } |
33 | 16 |
34 } // namespace | 17 PrefValueStore::PrefStoreKeeper::~PrefStoreKeeper() { |
18 if (pref_store_.get()) | |
19 pref_store_->RemoveObserver(this); | |
20 } | |
35 | 21 |
36 // static | 22 void PrefValueStore::PrefStoreKeeper::Initialize( |
37 PrefValueStore* PrefValueStore::CreatePrefValueStore( | 23 PrefValueStore* store, |
38 const FilePath& pref_filename, | 24 PrefStore* pref_store, |
39 Profile* profile, | 25 PrefValueStore::PrefStoreType type) { |
40 bool user_only) { | 26 if (pref_store_.get()) |
41 using policy::ConfigurationPolicyPrefStore; | 27 pref_store_->RemoveObserver(this); |
42 ConfigurationPolicyPrefStore* managed = NULL; | 28 type_ = type; |
43 ConfigurationPolicyPrefStore* device_management = NULL; | 29 pref_value_store_ = store; |
44 ExtensionPrefStore* extension = NULL; | 30 pref_store_.reset(pref_store); |
45 CommandLinePrefStore* command_line = NULL; | 31 if (pref_store_.get()) |
46 ConfigurationPolicyPrefStore* recommended = NULL; | 32 pref_store_->AddObserver(this); |
33 } | |
47 | 34 |
48 JsonPrefStore* user = new JsonPrefStore( | 35 void PrefValueStore::PrefStoreKeeper::OnPrefValueChanged( |
49 pref_filename, | 36 const std::string& key) { |
50 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); | 37 pref_value_store_->PrefValueChangedInStore(key, type_); |
51 DefaultPrefStore* default_store = new DefaultPrefStore(); | 38 } |
52 | 39 |
53 if (!user_only) { | 40 void PrefValueStore::PrefStoreKeeper::OnInitializationCompleted() { |
54 managed = | 41 pref_value_store_->InitializationCompleteForStore(type_); |
55 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore(); | 42 } |
56 device_management = | 43 |
57 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( | 44 PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, |
58 profile); | 45 PrefStore* device_management_prefs, |
59 extension = new ExtensionPrefStore(profile, PrefNotifier::EXTENSION_STORE); | 46 PrefStore* extension_prefs, |
60 command_line = new CommandLinePrefStore(CommandLine::ForCurrentProcess()); | 47 PrefStore* command_line_prefs, |
61 recommended = | 48 PrefStore* user_prefs, |
62 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore(); | 49 PrefStore* recommended_prefs, |
63 } | 50 PrefStore* default_prefs, |
64 return new PrefValueStore(managed, device_management, extension, | 51 PrefNotifier* pref_notifier, |
65 command_line, user, recommended, default_store, | 52 Profile* profile) |
66 profile); | 53 : pref_notifier_(pref_notifier), |
54 profile_(profile) { | |
55 // NULL default pref store is usually bad, but may be OK for some unit tests. | |
56 if (!default_prefs) | |
57 LOG(WARNING) << "default pref store is null"; | |
58 InitPrefStore(MANAGED_PLATFORM_STORE, managed_platform_prefs); | |
59 InitPrefStore(DEVICE_MANAGEMENT_STORE, device_management_prefs); | |
60 InitPrefStore(EXTENSION_STORE, extension_prefs); | |
61 InitPrefStore(COMMAND_LINE_STORE, command_line_prefs); | |
62 InitPrefStore(USER_STORE, user_prefs); | |
63 InitPrefStore(RECOMMENDED_STORE, recommended_prefs); | |
64 InitPrefStore(DEFAULT_STORE, default_prefs); | |
65 | |
66 // TODO(mnissler): Remove after policy refresh cleanup. | |
67 registrar_.Add(this, | |
68 NotificationType(NotificationType::POLICY_CHANGED), | |
69 NotificationService::AllSources()); | |
70 | |
71 CheckInitializationCompleted(); | |
67 } | 72 } |
68 | 73 |
69 PrefValueStore::~PrefValueStore() {} | 74 PrefValueStore::~PrefValueStore() {} |
70 | 75 |
71 bool PrefValueStore::GetValue(const std::string& name, | 76 bool PrefValueStore::GetValue(const std::string& name, |
72 Value** out_value) const { | 77 Value** out_value) const { |
73 // Check the |PrefStore|s in order of their priority from highest to lowest | 78 // Check the |PrefStore|s in order of their priority from highest to lowest |
74 // to find the value of the preference described by the given preference name. | 79 // to find the value of the preference described by the given preference name. |
75 for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | 80 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
76 if (GetValueFromStore(name.c_str(), | 81 if (GetValueFromStore(name.c_str(), static_cast<PrefStoreType>(i), |
77 static_cast<PrefNotifier::PrefStoreType>(i), | |
78 out_value)) | 82 out_value)) |
79 return true; | 83 return true; |
80 } | 84 } |
81 return false; | 85 return false; |
82 } | 86 } |
83 | 87 |
84 bool PrefValueStore::GetUserValue(const std::string& name, | 88 bool PrefValueStore::GetUserValue(const std::string& name, |
85 Value** out_value) const { | 89 Value** out_value) const { |
86 return GetValueFromStore(name.c_str(), PrefNotifier::USER_STORE, out_value); | 90 return GetValueFromStore(name.c_str(), USER_STORE, out_value); |
87 } | 91 } |
88 | 92 |
89 void PrefValueStore::RegisterPreferenceType(const std::string& name, | 93 void PrefValueStore::RegisterPreferenceType(const std::string& name, |
90 Value::ValueType type) { | 94 Value::ValueType type) { |
91 pref_types_[name] = type; | 95 pref_types_[name] = type; |
92 } | 96 } |
93 | 97 |
94 Value::ValueType PrefValueStore::GetRegisteredType( | 98 Value::ValueType PrefValueStore::GetRegisteredType( |
95 const std::string& name) const { | 99 const std::string& name) const { |
96 PrefTypeMap::const_iterator found = pref_types_.find(name); | 100 PrefTypeMap::const_iterator found = pref_types_.find(name); |
97 if (found == pref_types_.end()) | 101 if (found == pref_types_.end()) |
98 return Value::TYPE_NULL; | 102 return Value::TYPE_NULL; |
99 return found->second; | 103 return found->second; |
100 } | 104 } |
101 | 105 |
102 bool PrefValueStore::WritePrefs() { | 106 bool PrefValueStore::WritePrefs() { |
103 bool success = true; | 107 bool success = true; |
104 for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | 108 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
105 if (pref_stores_[i].get()) | 109 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); |
106 success = pref_stores_[i]->WritePrefs() && success; | 110 if (store) |
111 success = store->WritePrefs() && success; | |
107 } | 112 } |
108 return success; | 113 return success; |
109 } | 114 } |
110 | 115 |
111 void PrefValueStore::ScheduleWritePrefs() { | 116 void PrefValueStore::ScheduleWritePrefs() { |
112 for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | 117 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
113 if (pref_stores_[i].get()) | 118 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); |
114 pref_stores_[i]->ScheduleWritePrefs(); | 119 if (store) |
120 store->ScheduleWritePrefs(); | |
115 } | 121 } |
116 } | 122 } |
117 | 123 |
118 PrefStore::PrefReadError PrefValueStore::ReadPrefs() { | 124 PrefStore::PrefReadError PrefValueStore::ReadPrefs() { |
119 PrefStore::PrefReadError result = PrefStore::PREF_READ_ERROR_NONE; | 125 PrefStore::PrefReadError result = PrefStore::PREF_READ_ERROR_NONE; |
120 for (size_t i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | 126 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
121 if (pref_stores_[i].get()) { | 127 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); |
122 PrefStore::PrefReadError this_error = pref_stores_[i]->ReadPrefs(); | 128 if (store) { |
129 PrefStore::PrefReadError this_error = store->ReadPrefs(); | |
123 if (result == PrefStore::PREF_READ_ERROR_NONE) | 130 if (result == PrefStore::PREF_READ_ERROR_NONE) |
124 result = this_error; | 131 result = this_error; |
125 } | 132 } |
126 } | 133 } |
127 | 134 |
128 if (HasPolicyConflictingUserProxySettings()) { | 135 if (HasPolicyConflictingUserProxySettings()) { |
129 LOG(WARNING) << "user-requested proxy options have been overridden" | 136 LOG(WARNING) << "user-requested proxy options have been overridden" |
130 << " by a proxy configuration specified in a centrally" | 137 << " by a proxy configuration specified in a centrally" |
131 << " administered policy."; | 138 << " administered policy."; |
132 } | 139 } |
133 | 140 |
134 // TODO(markusheintz): Return a better error status: maybe a struct with | 141 // TODO(markusheintz): Return a better error status: maybe a struct with |
135 // the error status of all PrefStores. | 142 // the error status of all PrefStores. |
136 return result; | 143 return result; |
137 } | 144 } |
138 | 145 |
139 bool PrefValueStore::HasPrefPath(const char* path) const { | 146 bool PrefValueStore::HasPrefPath(const char* path) const { |
140 Value* tmp_value = NULL; | 147 Value* tmp_value = NULL; |
141 const std::string name(path); | 148 const std::string name(path); |
142 bool rv = GetValue(name, &tmp_value); | 149 bool rv = GetValue(name, &tmp_value); |
143 // Merely registering a pref doesn't count as "having" it: we require a | 150 // Merely registering a pref doesn't count as "having" it: we require a |
144 // non-default value set. | 151 // non-default value set. |
145 return rv && !PrefValueFromDefaultStore(path); | 152 return rv && !PrefValueFromDefaultStore(path); |
146 } | 153 } |
147 | 154 |
148 bool PrefValueStore::PrefHasChanged(const char* path, | 155 void PrefValueStore::NotifyPrefChanged( |
149 PrefNotifier::PrefStoreType new_store) { | 156 const char* path, |
150 DCHECK(new_store != PrefNotifier::INVALID_STORE); | 157 PrefValueStore::PrefStoreType new_store) { |
151 // Replying that the pref has changed may cause problems, but it's the safer | 158 DCHECK(new_store != INVALID_STORE); |
152 // choice. | |
153 if (new_store == PrefNotifier::INVALID_STORE) | |
154 return true; | |
155 | 159 |
156 PrefNotifier::PrefStoreType controller = ControllingPrefStoreForPref(path); | 160 bool changed = true; |
157 DCHECK(controller != PrefNotifier::INVALID_STORE); | 161 // Replying that the pref has changed in case the new store is invalid may |
158 if (controller == PrefNotifier::INVALID_STORE) | 162 // cause problems, but it's the safer choice. |
159 return true; | 163 if (new_store != INVALID_STORE) { |
164 PrefStoreType controller = ControllingPrefStoreForPref(path); | |
165 DCHECK(controller != INVALID_STORE); | |
166 // If the pref is controlled by a higher-priority store, its effective value | |
167 // cannot have changed. | |
168 if (controller != INVALID_STORE && | |
169 controller < new_store) { | |
170 changed = false; | |
171 } | |
172 } | |
160 | 173 |
161 // If the pref is controlled by a higher-priority store, its effective value | 174 if (changed) |
162 // cannot have changed. | 175 pref_notifier_->OnPreferenceChanged(path); |
163 if (controller < new_store) | |
164 return false; | |
165 | |
166 // Otherwise, we take the pref store's word that something changed. | |
167 return true; | |
168 } | 176 } |
169 | 177 |
170 // Note the |DictionaryValue| referenced by the |PrefStore| USER_STORE | 178 void PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) { |
171 // (returned by the method prefs()) takes the ownership of the Value referenced | 179 DCHECK(in_value); |
172 // by in_value. | |
173 bool PrefValueStore::SetUserPrefValue(const char* name, Value* in_value) { | |
174 Value* old_value = NULL; | 180 Value* old_value = NULL; |
175 pref_stores_[PrefNotifier::USER_STORE]->prefs()->Get(name, &old_value); | 181 GetPrefStore(USER_STORE)->prefs()->Get(name, &old_value); |
176 bool value_changed = !(old_value && old_value->Equals(in_value)); | 182 bool value_changed = !old_value || !old_value->Equals(in_value); |
183 GetPrefStore(USER_STORE)->prefs()->Set(name, in_value); | |
177 | 184 |
178 pref_stores_[PrefNotifier::USER_STORE]->prefs()->Set(name, in_value); | 185 if (value_changed) |
179 return value_changed; | 186 NotifyPrefChanged(name, USER_STORE); |
danno
2010/12/02 10:31:52
The user preference store should send this. Add TO
Mattias Nissler (ping if slow)
2010/12/02 16:38:24
Done.
| |
180 } | 187 } |
181 | 188 |
182 // Note the |DictionaryValue| referenced by the |PrefStore| DEFAULT_STORE | 189 void PrefValueStore::PutUserPrefValue(const char* name, Value* in_value) { |
183 // (returned by the method prefs()) takes the ownership of the Value referenced | 190 DCHECK(in_value); |
184 // by in_value. | 191 GetPrefStore(USER_STORE)->prefs()->Set(name, in_value); |
185 void PrefValueStore::SetDefaultPrefValue(const char* name, Value* in_value) { | |
186 pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Set(name, in_value); | |
187 } | 192 } |
188 | 193 |
189 bool PrefValueStore::ReadOnly() { | 194 bool PrefValueStore::ReadOnly() { |
190 return pref_stores_[PrefNotifier::USER_STORE]->ReadOnly(); | 195 return GetPrefStore(USER_STORE)->ReadOnly(); |
191 } | 196 } |
192 | 197 |
193 bool PrefValueStore::RemoveUserPrefValue(const char* name) { | 198 void PrefValueStore::RemoveUserPrefValue(const char* name) { |
194 if (pref_stores_[PrefNotifier::USER_STORE].get()) { | 199 if (GetPrefStore(USER_STORE)) { |
195 return pref_stores_[PrefNotifier::USER_STORE]->prefs()->Remove(name, NULL); | 200 if (GetPrefStore(USER_STORE)->prefs()->Remove(name, NULL)) |
201 NotifyPrefChanged(name, USER_STORE); | |
danno
2010/12/02 10:31:52
The user preference store should send this. Add TO
Mattias Nissler (ping if slow)
2010/12/02 16:38:24
Done.
| |
202 } | |
203 } | |
204 | |
205 bool PrefValueStore::PrefValueInManagedPlatformStore(const char* name) const { | |
206 return PrefValueInStore(name, MANAGED_PLATFORM_STORE); | |
207 } | |
208 | |
209 bool PrefValueStore::PrefValueInDeviceManagementStore(const char* name) const { | |
210 return PrefValueInStore(name, DEVICE_MANAGEMENT_STORE); | |
211 } | |
212 | |
213 bool PrefValueStore::PrefValueInExtensionStore(const char* name) const { | |
214 return PrefValueInStore(name, EXTENSION_STORE); | |
215 } | |
216 | |
217 bool PrefValueStore::PrefValueInUserStore(const char* name) const { | |
218 return PrefValueInStore(name, USER_STORE); | |
219 } | |
220 | |
221 bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const { | |
222 return ControllingPrefStoreForPref(name) == EXTENSION_STORE; | |
223 } | |
224 | |
225 bool PrefValueStore::PrefValueFromUserStore(const char* name) const { | |
226 return ControllingPrefStoreForPref(name) == USER_STORE; | |
227 } | |
228 | |
229 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { | |
230 return ControllingPrefStoreForPref(name) == DEFAULT_STORE; | |
231 } | |
232 | |
233 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { | |
234 PrefStoreType effective_store = ControllingPrefStoreForPref(name); | |
235 return effective_store >= USER_STORE || | |
236 effective_store == INVALID_STORE; | |
237 } | |
238 | |
239 bool PrefValueStore::HasPolicyConflictingUserProxySettings() { | |
240 using policy::ConfigurationPolicyPrefStore; | |
241 ConfigurationPolicyPrefStore::ProxyPreferenceSet proxy_prefs; | |
242 ConfigurationPolicyPrefStore::GetProxyPreferenceSet(&proxy_prefs); | |
243 ConfigurationPolicyPrefStore::ProxyPreferenceSet::const_iterator i; | |
244 for (i = proxy_prefs.begin(); i != proxy_prefs.end(); ++i) { | |
245 if ((PrefValueInManagedPlatformStore(*i) || | |
246 PrefValueInDeviceManagementStore(*i)) && | |
247 PrefValueInStoreRange(*i, | |
248 COMMAND_LINE_STORE, | |
249 USER_STORE)) | |
250 return true; | |
196 } | 251 } |
197 return false; | 252 return false; |
198 } | 253 } |
199 | 254 |
200 bool PrefValueStore::PrefValueInManagedPlatformStore(const char* name) const { | 255 // Returns true if the actual value is a valid type for the expected type when |
201 return PrefValueInStore(name, PrefNotifier::MANAGED_PLATFORM_STORE); | 256 // found in the given store. |
257 bool PrefValueStore::IsValidType(Value::ValueType expected, | |
258 Value::ValueType actual, | |
259 PrefValueStore::PrefStoreType store) { | |
260 if (expected == actual) | |
261 return true; | |
262 | |
263 // Dictionaries and lists are allowed to hold TYPE_NULL values too, but only | |
264 // in the default pref store. | |
265 if (store == DEFAULT_STORE && | |
266 actual == Value::TYPE_NULL && | |
267 (expected == Value::TYPE_DICTIONARY || expected == Value::TYPE_LIST)) { | |
268 return true; | |
269 } | |
270 return false; | |
202 } | 271 } |
203 | 272 |
204 bool PrefValueStore::PrefValueInDeviceManagementStore(const char* name) const { | 273 bool PrefValueStore::PrefValueInStore( |
205 return PrefValueInStore(name, PrefNotifier::DEVICE_MANAGEMENT_STORE); | 274 const char* name, |
206 } | 275 PrefValueStore::PrefStoreType store) const { |
207 | 276 // Declare a temp Value* and call GetValueFromStore, |
208 bool PrefValueStore::PrefValueInExtensionStore(const char* name) const { | 277 // ignoring the output value. |
209 return PrefValueInStore(name, PrefNotifier::EXTENSION_STORE); | 278 Value* tmp_value = NULL; |
210 } | 279 return GetValueFromStore(name, store, &tmp_value); |
211 | |
212 bool PrefValueStore::PrefValueInUserStore(const char* name) const { | |
213 return PrefValueInStore(name, PrefNotifier::USER_STORE); | |
214 } | 280 } |
215 | 281 |
216 bool PrefValueStore::PrefValueInStoreRange( | 282 bool PrefValueStore::PrefValueInStoreRange( |
217 const char* name, | 283 const char* name, |
218 PrefNotifier::PrefStoreType first_checked_store, | 284 PrefValueStore::PrefStoreType first_checked_store, |
219 PrefNotifier::PrefStoreType last_checked_store) { | 285 PrefValueStore::PrefStoreType last_checked_store) { |
220 if (first_checked_store > last_checked_store) { | 286 if (first_checked_store > last_checked_store) { |
221 NOTREACHED(); | 287 NOTREACHED(); |
222 return false; | 288 return false; |
223 } | 289 } |
224 | 290 |
225 for (size_t i = first_checked_store; | 291 for (size_t i = first_checked_store; |
226 i <= static_cast<size_t>(last_checked_store); ++i) { | 292 i <= static_cast<size_t>(last_checked_store); ++i) { |
227 if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i))) | 293 if (PrefValueInStore(name, static_cast<PrefStoreType>(i))) |
228 return true; | 294 return true; |
229 } | 295 } |
230 return false; | 296 return false; |
231 } | 297 } |
232 | 298 |
233 bool PrefValueStore::PrefValueFromExtensionStore(const char* name) const { | 299 PrefValueStore::PrefStoreType PrefValueStore::ControllingPrefStoreForPref( |
234 return ControllingPrefStoreForPref(name) == PrefNotifier::EXTENSION_STORE; | 300 const char* name) const { |
301 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
302 if (PrefValueInStore(name, static_cast<PrefStoreType>(i))) | |
303 return static_cast<PrefStoreType>(i); | |
304 } | |
305 return INVALID_STORE; | |
235 } | 306 } |
236 | 307 |
237 bool PrefValueStore::PrefValueFromUserStore(const char* name) const { | 308 bool PrefValueStore::GetValueFromStore(const char* name, |
238 return ControllingPrefStoreForPref(name) == PrefNotifier::USER_STORE; | 309 PrefValueStore::PrefStoreType store_type, |
239 } | 310 Value** out_value) const { |
240 | |
241 bool PrefValueStore::PrefValueFromDefaultStore(const char* name) const { | |
242 return ControllingPrefStoreForPref(name) == PrefNotifier::DEFAULT_STORE; | |
243 } | |
244 | |
245 bool PrefValueStore::PrefValueUserModifiable(const char* name) const { | |
246 PrefNotifier::PrefStoreType effective_store = | |
247 ControllingPrefStoreForPref(name); | |
248 return effective_store >= PrefNotifier::USER_STORE || | |
249 effective_store == PrefNotifier::INVALID_STORE; | |
250 } | |
251 | |
252 PrefNotifier::PrefStoreType PrefValueStore::ControllingPrefStoreForPref( | |
253 const char* name) const { | |
254 for (int i = 0; i <= PrefNotifier::PREF_STORE_TYPE_MAX; ++i) { | |
255 if (PrefValueInStore(name, static_cast<PrefNotifier::PrefStoreType>(i))) | |
256 return static_cast<PrefNotifier::PrefStoreType>(i); | |
257 } | |
258 return PrefNotifier::INVALID_STORE; | |
259 } | |
260 | |
261 bool PrefValueStore::PrefValueInStore( | |
262 const char* name, | |
263 PrefNotifier::PrefStoreType store) const { | |
264 // Declare a temp Value* and call GetValueFromStore, | |
265 // ignoring the output value. | |
266 Value* tmp_value = NULL; | |
267 return GetValueFromStore(name, store, &tmp_value); | |
268 } | |
269 | |
270 bool PrefValueStore::GetValueFromStore( | |
271 const char* name, | |
272 PrefNotifier::PrefStoreType store, | |
273 Value** out_value) const { | |
274 // Only return true if we find a value and it is the correct type, so stale | 311 // Only return true if we find a value and it is the correct type, so stale |
275 // values with the incorrect type will be ignored. | 312 // values with the incorrect type will be ignored. |
276 if (pref_stores_[store].get() && | 313 const PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(store_type)); |
277 pref_stores_[store]->prefs()->Get(name, out_value)) { | 314 if (store && store->prefs()->Get(name, out_value)) { |
278 // If the value is the sentinel that redirects to the default | 315 // If the value is the sentinel that redirects to the default |
279 // store, re-fetch the value from the default store explicitly. | 316 // store, re-fetch the value from the default store explicitly. |
280 // Because the default values are not available when creating | 317 // Because the default values are not available when creating |
281 // stores, the default value must be fetched dynamically for every | 318 // stores, the default value must be fetched dynamically for every |
282 // redirect. | 319 // redirect. |
283 if (PrefStore::IsUseDefaultSentinelValue(*out_value)) { | 320 if (PrefStore::IsUseDefaultSentinelValue(*out_value)) { |
284 DCHECK(pref_stores_[PrefNotifier::DEFAULT_STORE].get()); | 321 DCHECK(GetPrefStore(DEFAULT_STORE)); |
285 if (!pref_stores_[PrefNotifier::DEFAULT_STORE]->prefs()->Get(name, | 322 if (!GetPrefStore(DEFAULT_STORE)->prefs()->Get(name, out_value)) { |
286 out_value)) { | |
287 *out_value = NULL; | 323 *out_value = NULL; |
288 return false; | 324 return false; |
289 } | 325 } |
290 store = PrefNotifier::DEFAULT_STORE; | 326 store_type = DEFAULT_STORE; |
291 } | 327 } |
292 if (IsValidType(GetRegisteredType(name), (*out_value)->GetType(), store)) | 328 if (IsValidType(GetRegisteredType(name), |
329 (*out_value)->GetType(), | |
330 store_type)) { | |
293 return true; | 331 return true; |
332 } | |
294 } | 333 } |
295 // No valid value found for the given preference name: set the return false. | 334 // No valid value found for the given preference name: set the return false. |
296 *out_value = NULL; | 335 *out_value = NULL; |
297 return false; | 336 return false; |
298 } | 337 } |
299 | 338 |
300 void PrefValueStore::RefreshPolicyPrefsOnFileThread( | 339 void PrefValueStore::RefreshPolicyPrefsOnFileThread( |
301 BrowserThread::ID calling_thread_id, | 340 BrowserThread::ID calling_thread_id, |
302 PrefStore* new_managed_platform_pref_store, | 341 PrefStore* new_managed_platform_pref_store, |
303 PrefStore* new_device_management_pref_store, | 342 PrefStore* new_device_management_pref_store, |
304 PrefStore* new_recommended_pref_store, | 343 PrefStore* new_recommended_pref_store) { |
305 AfterRefreshCallback* callback_pointer) { | |
306 scoped_ptr<AfterRefreshCallback> callback(callback_pointer); | |
307 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 344 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
308 scoped_ptr<PrefStore> managed_platform_pref_store( | 345 scoped_ptr<PrefStore> managed_platform_pref_store( |
309 new_managed_platform_pref_store); | 346 new_managed_platform_pref_store); |
310 scoped_ptr<PrefStore> device_management_pref_store( | 347 scoped_ptr<PrefStore> device_management_pref_store( |
311 new_device_management_pref_store); | 348 new_device_management_pref_store); |
312 scoped_ptr<PrefStore> recommended_pref_store(new_recommended_pref_store); | 349 scoped_ptr<PrefStore> recommended_pref_store(new_recommended_pref_store); |
313 | 350 |
314 PrefStore::PrefReadError read_error = | 351 PrefStore::PrefReadError read_error = |
315 new_managed_platform_pref_store->ReadPrefs(); | 352 new_managed_platform_pref_store->ReadPrefs(); |
316 if (read_error != PrefStore::PREF_READ_ERROR_NONE) { | 353 if (read_error != PrefStore::PREF_READ_ERROR_NONE) { |
(...skipping 15 matching lines...) Expand all Loading... | |
332 << read_error; | 369 << read_error; |
333 return; | 370 return; |
334 } | 371 } |
335 | 372 |
336 BrowserThread::PostTask( | 373 BrowserThread::PostTask( |
337 calling_thread_id, FROM_HERE, | 374 calling_thread_id, FROM_HERE, |
338 NewRunnableMethod(this, | 375 NewRunnableMethod(this, |
339 &PrefValueStore::RefreshPolicyPrefsCompletion, | 376 &PrefValueStore::RefreshPolicyPrefsCompletion, |
340 managed_platform_pref_store.release(), | 377 managed_platform_pref_store.release(), |
341 device_management_pref_store.release(), | 378 device_management_pref_store.release(), |
342 recommended_pref_store.release(), | 379 recommended_pref_store.release())); |
343 callback.release())); | 380 } |
381 | |
382 void PrefValueStore::RefreshPolicyPrefs() { | |
383 using policy::ConfigurationPolicyPrefStore; | |
384 // Because loading of policy information must happen on the FILE | |
385 // thread, it's not possible to just replace the contents of the | |
386 // managed and recommended stores in place due to possible | |
387 // concurrent access from the UI thread. Instead, new stores are | |
388 // created and the refreshed policy read into them. The new stores | |
389 // are swapped with the old from a Task on the UI thread after the | |
390 // load is complete. | |
391 PrefStore* new_managed_platform_pref_store( | |
392 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); | |
393 PrefStore* new_device_management_pref_store( | |
394 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( | |
395 profile_)); | |
396 PrefStore* new_recommended_pref_store( | |
397 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); | |
398 BrowserThread::ID current_thread_id; | |
399 CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); | |
400 BrowserThread::PostTask( | |
401 BrowserThread::FILE, FROM_HERE, | |
402 NewRunnableMethod(this, | |
403 &PrefValueStore::RefreshPolicyPrefsOnFileThread, | |
404 current_thread_id, | |
405 new_managed_platform_pref_store, | |
406 new_device_management_pref_store, | |
407 new_recommended_pref_store)); | |
344 } | 408 } |
345 | 409 |
346 void PrefValueStore::RefreshPolicyPrefsCompletion( | 410 void PrefValueStore::RefreshPolicyPrefsCompletion( |
347 PrefStore* new_managed_platform_pref_store, | 411 PrefStore* new_managed_platform_pref_store, |
348 PrefStore* new_device_management_pref_store, | 412 PrefStore* new_device_management_pref_store, |
349 PrefStore* new_recommended_pref_store, | 413 PrefStore* new_recommended_pref_store) { |
350 AfterRefreshCallback* callback_pointer) { | |
351 scoped_ptr<AfterRefreshCallback> callback(callback_pointer); | |
352 | |
353 // Determine the paths of all the changed preferences values in the three | 414 // Determine the paths of all the changed preferences values in the three |
354 // policy-related stores (managed platform, device management and | 415 // policy-related stores (managed platform, device management and |
355 // recommended). | 416 // recommended). |
356 DictionaryValue* managed_platform_prefs_before( | 417 DictionaryValue* managed_platform_prefs_before( |
357 pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE]->prefs()); | 418 GetPrefStore(MANAGED_PLATFORM_STORE)->prefs()); |
358 DictionaryValue* managed_platform_prefs_after( | 419 DictionaryValue* managed_platform_prefs_after( |
359 new_managed_platform_pref_store->prefs()); | 420 new_managed_platform_pref_store->prefs()); |
360 DictionaryValue* device_management_prefs_before( | 421 DictionaryValue* device_management_prefs_before( |
361 pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE]->prefs()); | 422 GetPrefStore(DEVICE_MANAGEMENT_STORE)->prefs()); |
362 DictionaryValue* device_management_prefs_after( | 423 DictionaryValue* device_management_prefs_after( |
363 new_device_management_pref_store->prefs()); | 424 new_device_management_pref_store->prefs()); |
364 DictionaryValue* recommended_prefs_before( | 425 DictionaryValue* recommended_prefs_before( |
365 pref_stores_[PrefNotifier::RECOMMENDED_STORE]->prefs()); | 426 GetPrefStore(RECOMMENDED_STORE)->prefs()); |
366 DictionaryValue* recommended_prefs_after(new_recommended_pref_store->prefs()); | 427 DictionaryValue* recommended_prefs_after(new_recommended_pref_store->prefs()); |
367 | 428 |
368 std::vector<std::string> changed_managed_platform_paths; | 429 std::vector<std::string> changed_managed_platform_paths; |
369 managed_platform_prefs_before->GetDifferingPaths(managed_platform_prefs_after, | 430 managed_platform_prefs_before->GetDifferingPaths(managed_platform_prefs_after, |
370 &changed_managed_platform_paths); | 431 &changed_managed_platform_paths); |
371 | 432 |
372 std::vector<std::string> changed_device_management_paths; | 433 std::vector<std::string> changed_device_management_paths; |
373 device_management_prefs_before->GetDifferingPaths( | 434 device_management_prefs_before->GetDifferingPaths( |
374 device_management_prefs_after, | 435 device_management_prefs_after, |
375 &changed_device_management_paths); | 436 &changed_device_management_paths); |
(...skipping 25 matching lines...) Expand all Loading... | |
401 changed_recommended_paths.begin(), | 462 changed_recommended_paths.begin(), |
402 changed_recommended_paths.end(), | 463 changed_recommended_paths.end(), |
403 changed_paths.begin()); | 464 changed_paths.begin()); |
404 changed_paths.resize(last_insert - changed_paths.begin()); | 465 changed_paths.resize(last_insert - changed_paths.begin()); |
405 | 466 |
406 last_insert = unique(changed_paths.begin(), changed_paths.end()); | 467 last_insert = unique(changed_paths.begin(), changed_paths.end()); |
407 changed_paths.resize(last_insert - changed_paths.begin()); | 468 changed_paths.resize(last_insert - changed_paths.begin()); |
408 | 469 |
409 // Replace the old stores with the new and send notification of the changed | 470 // Replace the old stores with the new and send notification of the changed |
410 // preferences. | 471 // preferences. |
411 pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE].reset( | 472 InitPrefStore(MANAGED_PLATFORM_STORE, new_managed_platform_pref_store); |
412 new_managed_platform_pref_store); | 473 InitPrefStore(DEVICE_MANAGEMENT_STORE, new_device_management_pref_store); |
413 pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE].reset( | 474 InitPrefStore(RECOMMENDED_STORE, new_recommended_pref_store); |
414 new_device_management_pref_store); | 475 |
415 pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset( | 476 std::vector<std::string>::const_iterator current; |
416 new_recommended_pref_store); | 477 for (current = changed_paths.begin(); |
417 callback->Run(changed_paths); | 478 current != changed_paths.end(); |
479 ++current) { | |
480 pref_notifier_->OnPreferenceChanged(current->c_str()); | |
481 } | |
418 } | 482 } |
419 | 483 |
420 void PrefValueStore::RefreshPolicyPrefs( | 484 void PrefValueStore::Observe(NotificationType type, |
421 AfterRefreshCallback* callback) { | 485 const NotificationSource& source, |
422 using policy::ConfigurationPolicyPrefStore; | 486 const NotificationDetails& details) { |
423 // Because loading of policy information must happen on the FILE | 487 if (type == NotificationType::POLICY_CHANGED) |
424 // thread, it's not possible to just replace the contents of the | 488 RefreshPolicyPrefs(); |
425 // managed and recommended stores in place due to possible | |
426 // concurrent access from the UI thread. Instead, new stores are | |
427 // created and the refreshed policy read into them. The new stores | |
428 // are swapped with the old from a Task on the UI thread after the | |
429 // load is complete. | |
430 PrefStore* new_managed_platform_pref_store( | |
431 ConfigurationPolicyPrefStore::CreateManagedPlatformPolicyPrefStore()); | |
432 PrefStore* new_device_management_pref_store( | |
433 ConfigurationPolicyPrefStore::CreateDeviceManagementPolicyPrefStore( | |
434 profile_)); | |
435 PrefStore* new_recommended_pref_store( | |
436 ConfigurationPolicyPrefStore::CreateRecommendedPolicyPrefStore()); | |
437 BrowserThread::ID current_thread_id; | |
438 CHECK(BrowserThread::GetCurrentThreadIdentifier(¤t_thread_id)); | |
439 BrowserThread::PostTask( | |
440 BrowserThread::FILE, FROM_HERE, | |
441 NewRunnableMethod(this, | |
442 &PrefValueStore::RefreshPolicyPrefsOnFileThread, | |
443 current_thread_id, | |
444 new_managed_platform_pref_store, | |
445 new_device_management_pref_store, | |
446 new_recommended_pref_store, | |
447 callback)); | |
448 } | 489 } |
449 | 490 |
450 bool PrefValueStore::HasPolicyConflictingUserProxySettings() { | 491 void PrefValueStore::PrefValueChangedInStore( |
451 using policy::ConfigurationPolicyPrefStore; | 492 const std::string& key, |
452 ConfigurationPolicyPrefStore::ProxyPreferenceSet proxy_prefs; | 493 PrefValueStore::PrefStoreType type) { |
453 ConfigurationPolicyPrefStore::GetProxyPreferenceSet(&proxy_prefs); | 494 NotifyPrefChanged(key.c_str(), type); |
454 ConfigurationPolicyPrefStore::ProxyPreferenceSet::const_iterator i; | |
455 for (i = proxy_prefs.begin(); i != proxy_prefs.end(); ++i) { | |
456 if ((PrefValueInManagedPlatformStore(*i) || | |
457 PrefValueInDeviceManagementStore(*i)) && | |
458 PrefValueInStoreRange(*i, | |
459 PrefNotifier::COMMAND_LINE_STORE, | |
460 PrefNotifier::USER_STORE)) | |
461 return true; | |
462 } | |
463 return false; | |
464 } | 495 } |
465 | 496 |
466 PrefValueStore::PrefValueStore(PrefStore* managed_platform_prefs, | 497 void PrefValueStore::InitializationCompleteForStore( |
467 PrefStore* device_management_prefs, | 498 PrefValueStore::PrefStoreType type) { |
468 PrefStore* extension_prefs, | 499 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { |
469 PrefStore* command_line_prefs, | 500 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); |
470 PrefStore* user_prefs, | 501 if (store && !store->IsInitializationComplete()) |
471 PrefStore* recommended_prefs, | 502 return; |
472 PrefStore* default_prefs, | 503 } |
473 Profile* profile) | 504 pref_notifier_->OnInitializationCompleted(); |
474 : profile_(profile) { | |
475 // NULL default pref store is usually bad, but may be OK for some unit tests. | |
476 if (!default_prefs) | |
477 LOG(WARNING) << "default pref store is null"; | |
478 pref_stores_[PrefNotifier::MANAGED_PLATFORM_STORE].reset( | |
479 managed_platform_prefs); | |
480 pref_stores_[PrefNotifier::DEVICE_MANAGEMENT_STORE].reset( | |
481 device_management_prefs); | |
482 pref_stores_[PrefNotifier::EXTENSION_STORE].reset(extension_prefs); | |
483 pref_stores_[PrefNotifier::COMMAND_LINE_STORE].reset(command_line_prefs); | |
484 pref_stores_[PrefNotifier::USER_STORE].reset(user_prefs); | |
485 pref_stores_[PrefNotifier::RECOMMENDED_STORE].reset(recommended_prefs); | |
486 pref_stores_[PrefNotifier::DEFAULT_STORE].reset(default_prefs); | |
487 } | 505 } |
506 | |
507 void PrefValueStore::InitPrefStore(PrefValueStore::PrefStoreType type, | |
508 PrefStore* pref_store) { | |
509 pref_stores_[type].Initialize(this, pref_store, type); | |
510 } | |
511 | |
512 void PrefValueStore::CheckInitializationCompleted() { | |
danno
2010/12/02 10:31:52
Code is missing? This needs to be called by the Ke
Mattias Nissler (ping if slow)
2010/12/02 16:38:24
Done.
| |
513 for (size_t i = 0; i <= PREF_STORE_TYPE_MAX; ++i) { | |
514 PrefStore* store = GetPrefStore(static_cast<PrefStoreType>(i)); | |
515 if (store && !store->IsInitializationComplete()) | |
516 return; | |
517 } | |
518 pref_notifier_->OnInitializationCompleted(); | |
519 } | |
520 | |
521 PrefStore* PrefValueStore::GetPrefStore(PrefValueStore::PrefStoreType type) { | |
522 return pref_stores_[type].store(); | |
523 } | |
524 | |
525 const PrefStore* PrefValueStore::GetPrefStore( | |
526 PrefValueStore::PrefStoreType type) const { | |
527 return pref_stores_[type].store(); | |
528 } | |
OLD | NEW |