Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Side by Side Diff: chrome/browser/prefs/pref_value_store.cc

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

Powered by Google App Engine
This is Rietveld 408576698