| 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 |