OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/common/json_pref_store.h" | 5 #include "chrome/common/json_pref_store.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/callback.h" | 10 #include "base/callback.h" |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 : path_(filename), | 141 : path_(filename), |
142 file_message_loop_proxy_(file_message_loop_proxy), | 142 file_message_loop_proxy_(file_message_loop_proxy), |
143 prefs_(new DictionaryValue()), | 143 prefs_(new DictionaryValue()), |
144 read_only_(false), | 144 read_only_(false), |
145 writer_(filename, file_message_loop_proxy), | 145 writer_(filename, file_message_loop_proxy), |
146 error_delegate_(NULL), | 146 error_delegate_(NULL), |
147 initialized_(false) { | 147 initialized_(false) { |
148 } | 148 } |
149 | 149 |
150 JsonPrefStore::~JsonPrefStore() { | 150 JsonPrefStore::~JsonPrefStore() { |
151 ResetCheckIfValueDestroyed(prefs_.get()); | |
152 CommitPendingWrite(); | 151 CommitPendingWrite(); |
153 } | 152 } |
154 | 153 |
155 PrefStore::ReadResult JsonPrefStore::GetValue(const std::string& key, | 154 PrefStore::ReadResult JsonPrefStore::GetValue(const std::string& key, |
156 const Value** result) const { | 155 const Value** result) const { |
157 Value* tmp = NULL; | 156 Value* tmp = NULL; |
158 if (prefs_->Get(key, &tmp)) { | 157 if (prefs_->Get(key, &tmp)) { |
159 if (result) | 158 if (result) |
160 *result = tmp; | 159 *result = tmp; |
161 return READ_OK; | 160 return READ_OK; |
(...skipping 12 matching lines...) Expand all Loading... |
174 bool JsonPrefStore::IsInitializationComplete() const { | 173 bool JsonPrefStore::IsInitializationComplete() const { |
175 return initialized_; | 174 return initialized_; |
176 } | 175 } |
177 | 176 |
178 PrefStore::ReadResult JsonPrefStore::GetMutableValue(const std::string& key, | 177 PrefStore::ReadResult JsonPrefStore::GetMutableValue(const std::string& key, |
179 Value** result) { | 178 Value** result) { |
180 return prefs_->Get(key, result) ? READ_OK : READ_NO_VALUE; | 179 return prefs_->Get(key, result) ? READ_OK : READ_NO_VALUE; |
181 } | 180 } |
182 | 181 |
183 void JsonPrefStore::SetValue(const std::string& key, Value* value) { | 182 void JsonPrefStore::SetValue(const std::string& key, Value* value) { |
184 SetValueImpl(key, value, SET_VALUE_NOTIFY); | 183 DCHECK(value); |
| 184 scoped_ptr<Value> new_value(value); |
| 185 Value* old_value = NULL; |
| 186 prefs_->Get(key, &old_value); |
| 187 if (!old_value || !value->Equals(old_value)) { |
| 188 prefs_->Set(key, new_value.release()); |
| 189 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); |
| 190 } |
185 } | 191 } |
186 | 192 |
187 void JsonPrefStore::SetValueSilently(const std::string& key, Value* value) { | 193 void JsonPrefStore::SetValueSilently(const std::string& key, Value* value) { |
188 SetValueImpl(key, value, SET_VALUE_DONT_NOTIFY); | 194 DCHECK(value); |
| 195 scoped_ptr<Value> new_value(value); |
| 196 Value* old_value = NULL; |
| 197 prefs_->Get(key, &old_value); |
| 198 if (!old_value || !value->Equals(old_value)) |
| 199 prefs_->Set(key, new_value.release()); |
189 } | 200 } |
190 | 201 |
191 void JsonPrefStore::RemoveValue(const std::string& key) { | 202 void JsonPrefStore::RemoveValue(const std::string& key) { |
192 Value* value = NULL; | 203 if (prefs_->Remove(key, NULL)) { |
193 bool path_existed = prefs_->Remove(key, &value); | |
194 scoped_ptr<Value> owned_value(value); | |
195 ResetCheckIfValueDestroyed(value); | |
196 if (path_existed) | |
197 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); | 204 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); |
| 205 } |
198 } | 206 } |
199 | 207 |
200 bool JsonPrefStore::ReadOnly() const { | 208 bool JsonPrefStore::ReadOnly() const { |
201 return read_only_; | 209 return read_only_; |
202 } | 210 } |
203 | 211 |
204 void JsonPrefStore::OnFileRead(Value* value_owned, | 212 void JsonPrefStore::OnFileRead(Value* value_owned, |
205 PersistentPrefStore::PrefReadError error, | 213 PersistentPrefStore::PrefReadError error, |
206 bool no_dir) { | 214 bool no_dir) { |
207 scoped_ptr<Value> value(value_owned); | 215 scoped_ptr<Value> value(value_owned); |
208 initialized_ = true; | 216 initialized_ = true; |
209 | 217 |
210 if (no_dir) { | 218 if (no_dir) { |
211 FOR_EACH_OBSERVER(PrefStore::Observer, | 219 FOR_EACH_OBSERVER(PrefStore::Observer, |
212 observers_, | 220 observers_, |
213 OnInitializationCompleted(false)); | 221 OnInitializationCompleted(false)); |
214 return; | 222 return; |
215 } | 223 } |
216 | 224 |
217 switch (error) { | 225 switch (error) { |
218 case PREF_READ_ERROR_ACCESS_DENIED: | 226 case PREF_READ_ERROR_ACCESS_DENIED: |
219 case PREF_READ_ERROR_FILE_OTHER: | 227 case PREF_READ_ERROR_FILE_OTHER: |
220 case PREF_READ_ERROR_FILE_LOCKED: | 228 case PREF_READ_ERROR_FILE_LOCKED: |
221 case PREF_READ_ERROR_JSON_TYPE: | 229 case PREF_READ_ERROR_JSON_TYPE: |
222 case PREF_READ_ERROR_FILE_NOT_SPECIFIED: | 230 case PREF_READ_ERROR_FILE_NOT_SPECIFIED: |
223 read_only_ = true; | 231 read_only_ = true; |
224 break; | 232 break; |
225 case PREF_READ_ERROR_NONE: | 233 case PREF_READ_ERROR_NONE: |
226 DCHECK(value.get()); | 234 DCHECK(value.get()); |
227 ResetCheckIfValueDestroyed(prefs_.get()); | |
228 prefs_.reset(static_cast<DictionaryValue*>(value.release())); | 235 prefs_.reset(static_cast<DictionaryValue*>(value.release())); |
229 break; | 236 break; |
230 case PREF_READ_ERROR_NO_FILE: | 237 case PREF_READ_ERROR_NO_FILE: |
231 // If the file just doesn't exist, maybe this is first run. In any case | 238 // If the file just doesn't exist, maybe this is first run. In any case |
232 // there's no harm in writing out default prefs in this case. | 239 // there's no harm in writing out default prefs in this case. |
233 break; | 240 break; |
234 case PREF_READ_ERROR_JSON_PARSE: | 241 case PREF_READ_ERROR_JSON_PARSE: |
235 case PREF_READ_ERROR_JSON_REPEAT: | 242 case PREF_READ_ERROR_JSON_REPEAT: |
236 break; | 243 break; |
237 default: | 244 default: |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 | 303 |
297 void JsonPrefStore::CommitPendingWrite() { | 304 void JsonPrefStore::CommitPendingWrite() { |
298 if (writer_.HasPendingWrite() && !read_only_) | 305 if (writer_.HasPendingWrite() && !read_only_) |
299 writer_.DoScheduledWrite(); | 306 writer_.DoScheduledWrite(); |
300 } | 307 } |
301 | 308 |
302 void JsonPrefStore::ReportValueChanged(const std::string& key) { | 309 void JsonPrefStore::ReportValueChanged(const std::string& key) { |
303 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); | 310 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); |
304 } | 311 } |
305 | 312 |
306 void JsonPrefStore::CheckIfValueDestroyed(const std::string& key) { | |
307 Value* value = NULL; | |
308 CHECK_EQ(READ_OK, GetMutableValue(key, &value)); | |
309 CHECK(value); | |
310 value->set_check_on_delete(true); | |
311 } | |
312 | |
313 bool JsonPrefStore::SerializeData(std::string* output) { | 313 bool JsonPrefStore::SerializeData(std::string* output) { |
314 // TODO(tc): Do we want to prune webkit preferences that match the default | 314 // TODO(tc): Do we want to prune webkit preferences that match the default |
315 // value? | 315 // value? |
316 JSONStringValueSerializer serializer(output); | 316 JSONStringValueSerializer serializer(output); |
317 serializer.set_pretty_print(true); | 317 serializer.set_pretty_print(true); |
318 scoped_ptr<DictionaryValue> copy(prefs_->DeepCopyWithoutEmptyChildren()); | 318 scoped_ptr<DictionaryValue> copy(prefs_->DeepCopyWithoutEmptyChildren()); |
319 return serializer.Serialize(*(copy.get())); | 319 return serializer.Serialize(*(copy.get())); |
320 } | 320 } |
321 | |
322 void JsonPrefStore::SetValueImpl(const std::string& key, | |
323 Value* value, | |
324 SetValueType type) { | |
325 DCHECK(value); | |
326 scoped_ptr<Value> new_value(value); | |
327 Value* old_value = NULL; | |
328 prefs_->Get(key, &old_value); | |
329 ResetCheckIfValueDestroyed(old_value); | |
330 if (!old_value || !value->Equals(old_value)) { | |
331 prefs_->Set(key, new_value.release()); | |
332 if (type == SET_VALUE_NOTIFY) | |
333 ReportValueChanged(key); | |
334 } | |
335 } | |
336 | |
337 // static | |
338 void JsonPrefStore::ResetCheckIfValueDestroyed(Value* value) { | |
339 if (!value) | |
340 return; | |
341 | |
342 value->set_check_on_delete(false); | |
343 | |
344 switch (value->GetType()) { | |
345 case Value::TYPE_DICTIONARY: { | |
346 DictionaryValue* dictionary = static_cast<DictionaryValue*>(value); | |
347 for (DictionaryValue::key_iterator i = dictionary->begin_keys(); | |
348 i != dictionary->end_keys(); ++i) { | |
349 Value* child_value = NULL; | |
350 dictionary->GetWithoutPathExpansion(*i, &child_value); | |
351 ResetCheckIfValueDestroyed(child_value); | |
352 } | |
353 break; | |
354 } | |
355 | |
356 case Value::TYPE_LIST: { | |
357 ListValue* list = static_cast<ListValue*>(value); | |
358 for (size_t i = 0; i < list->GetSize(); ++i) { | |
359 Value* child_value = NULL; | |
360 list->Get(i, &child_value); | |
361 ResetCheckIfValueDestroyed(child_value); | |
362 } | |
363 break; | |
364 } | |
365 | |
366 default: | |
367 break; | |
368 } | |
369 } | |
OLD | NEW |