OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/extensions/extension_pref_store.h" |
| 6 |
| 7 #include "base/logging.h" |
| 8 #include "base/values.h" |
| 9 #include "chrome/browser/pref_service.h" |
| 10 |
| 11 ExtensionPrefStore::ExtensionPrefStore(PrefService* pref_service) |
| 12 : pref_service_(pref_service), |
| 13 prefs_(new DictionaryValue()) { |
| 14 } |
| 15 |
| 16 // This could be sped up by keeping track of which extension currently controls |
| 17 // a given preference, among other optimizations. But we estimate that fewer |
| 18 // than 10 installed extensions will be trying to control any preferences, so |
| 19 // stick with this simpler algorithm until it causes a problem. |
| 20 void ExtensionPrefStore::UpdateOnePref(const wchar_t* path) { |
| 21 // Query the PrefService to find the current value for this pref. |
| 22 // pref_service_ might be null in unit tests. |
| 23 scoped_ptr<Value> old_value; |
| 24 if (pref_service_) { |
| 25 old_value.reset( |
| 26 pref_service_->FindPreference(path)->GetValue()->DeepCopy()); |
| 27 } |
| 28 |
| 29 // DictionaryValue::Set complains if a key is overwritten with the same |
| 30 // value, so delete it first. |
| 31 prefs_->Remove(path, NULL); |
| 32 |
| 33 // Find the first extension that wants to set this pref and use its value. |
| 34 for (ExtensionStack::iterator ext_iter = extension_stack_.begin(); |
| 35 ext_iter != extension_stack_.end(); ++ext_iter) { |
| 36 PrefValueMap::iterator value_iter = (*ext_iter)->pref_values->find(path); |
| 37 if (value_iter != (*ext_iter)->pref_values->end()) { |
| 38 prefs_->Set(path, (*value_iter).second->DeepCopy()); |
| 39 break; |
| 40 } |
| 41 } |
| 42 if (pref_service_) |
| 43 pref_service_->FireObserversIfChanged(path, old_value.get()); |
| 44 } |
| 45 |
| 46 void ExtensionPrefStore::UpdatePrefs(const PrefValueMap* pref_values) { |
| 47 for (PrefValueMap::const_iterator i = pref_values->begin(); |
| 48 i != pref_values->end(); ++i) { |
| 49 UpdateOnePref(i->first); |
| 50 } |
| 51 } |
| 52 |
| 53 void ExtensionPrefStore::InstallExtensionPref(std::string extension_id, |
| 54 const wchar_t* pref_path, |
| 55 Value* pref_value) { |
| 56 ExtensionStack::iterator i; |
| 57 for (i = extension_stack_.begin(); i != extension_stack_.end(); ++i) { |
| 58 if ((*i)->extension_id == extension_id) |
| 59 break; |
| 60 } |
| 61 |
| 62 // If this extension is already in the stack, update or add the value of this |
| 63 // preference, but don't change the extension's position in the stack. |
| 64 // Otherwise, push the new extension onto the stack. |
| 65 PrefValueMap* pref_values; |
| 66 if (i != extension_stack_.end()) { |
| 67 pref_values = (*i)->pref_values; |
| 68 (*pref_values)[pref_path] = pref_value; |
| 69 } else { |
| 70 pref_values = new PrefValueMap(); |
| 71 (*pref_values)[pref_path] = pref_value; |
| 72 |
| 73 ExtensionPrefs* extension_prefs = new ExtensionPrefs(); |
| 74 extension_prefs->extension_id = extension_id; |
| 75 extension_prefs->pref_values = pref_values; |
| 76 extension_stack_.push_front(extension_prefs); |
| 77 } |
| 78 |
| 79 // Look for an old value with the same type as the one we're modifying. |
| 80 UpdateOnePref(pref_path); |
| 81 } |
| 82 |
| 83 void ExtensionPrefStore::UninstallExtension(std::string extension_id) { |
| 84 // Remove this extension from the stack. |
| 85 scoped_ptr<PrefValueMap> pref_values; |
| 86 for (ExtensionStack::iterator i = extension_stack_.begin(); |
| 87 i != extension_stack_.end(); ++i) { |
| 88 if ((*i)->extension_id == extension_id) { |
| 89 pref_values.reset((*i)->pref_values); |
| 90 extension_stack_.erase(i); |
| 91 break; |
| 92 } |
| 93 } |
| 94 if (!pref_values.get()) |
| 95 return; |
| 96 |
| 97 UpdatePrefs(pref_values.get()); |
| 98 } |
| 99 |
| 100 void ExtensionPrefStore::GetExtensionIDs(std::vector<std::string>* result) { |
| 101 for (ExtensionStack::iterator i = extension_stack_.begin(); |
| 102 i != extension_stack_.end(); ++i) { |
| 103 (*result).push_back((*i)->extension_id); |
| 104 } |
| 105 } |
OLD | NEW |