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/extensions/extension_pref_store.h" | 5 #include "chrome/browser/extensions/extension_pref_store.h" |
6 | 6 |
| 7 #include <limits> |
| 8 |
7 #include "base/logging.h" | 9 #include "base/logging.h" |
8 #include "base/values.h" | 10 #include "base/values.h" |
9 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
| 12 #include "chrome/browser/extensions/extensions_service.h" |
| 13 #include "chrome/browser/extensions/extension_prefs.h" |
10 #include "chrome/browser/prefs/pref_service.h" | 14 #include "chrome/browser/prefs/pref_service.h" |
11 #include "chrome/browser/profile.h" | 15 #include "chrome/browser/profile.h" |
12 #include "chrome/common/extensions/extension.h" | 16 #include "chrome/common/extensions/extension.h" |
13 #include "chrome/common/notification_service.h" | 17 #include "chrome/common/notification_service.h" |
14 | 18 |
15 ExtensionPrefStore::ExtensionPrefStore(Profile* profile, | 19 ExtensionPrefStore::ExtensionPrefStore(Profile* profile, |
16 PrefNotifier::PrefStoreType type) | 20 PrefNotifier::PrefStoreType type) |
17 : prefs_(new DictionaryValue()), | 21 : prefs_(new DictionaryValue()), |
18 profile_(profile), | 22 profile_(profile), |
19 type_(type) { | 23 type_(type) { |
20 RegisterObservers(); | 24 RegisterObservers(); |
21 } | 25 } |
22 | 26 |
23 ExtensionPrefStore::~ExtensionPrefStore() { | 27 ExtensionPrefStore::~ExtensionPrefStore() { |
24 STLDeleteElements(&extension_stack_); | 28 STLDeleteElements(&extension_stack_); |
25 notification_registrar_.RemoveAll(); | 29 notification_registrar_.RemoveAll(); |
26 } | 30 } |
27 | 31 |
28 void ExtensionPrefStore::InstallExtensionPref(const Extension* extension, | 32 void ExtensionPrefStore::InstallExtensionPref(const Extension* extension, |
29 const char* new_pref_path, | 33 const char* new_pref_path, |
30 Value* new_pref_value) { | 34 Value* new_pref_value) { |
| 35 if (extension_stack_.empty()) |
| 36 LazyInit(); |
| 37 |
31 ExtensionStack::iterator i; | 38 ExtensionStack::iterator i; |
32 for (i = extension_stack_.begin(); i != extension_stack_.end(); ++i) { | 39 for (i = extension_stack_.begin(); i != extension_stack_.end(); ++i) { |
33 if ((*i)->extension == extension) | 40 if ((*i)->extension_id == extension->id()) |
34 break; | 41 break; |
35 } | 42 } |
36 | 43 |
37 // If this extension is not already in the stack, add it. Otherwise, update | 44 // If this extension is not already in the stack, add it. Otherwise, update |
38 // or add the value of this preference, but don't change the extension's | 45 // or add the value of this preference, but don't change the extension's |
39 // position in the stack. We store the extension even if this preference | 46 // position in the stack. We store the extension even if this preference |
40 // isn't registered with our PrefService, so that the ordering of extensions | 47 // isn't registered with our PrefService, so that the ordering of extensions |
41 // is consistent among all local-state and user ExtensionPrefStores. | 48 // is consistent among all local-state and user ExtensionPrefStores. |
42 PrefService* pref_service = GetPrefService(); | 49 PrefService* pref_service = GetPrefService(); |
43 // The pref_service may be NULL in unit testing. | 50 // The pref_service may be NULL in unit testing. |
44 bool is_registered_pref = (pref_service == NULL || | 51 bool is_registered_pref = (pref_service == NULL || |
45 pref_service->FindPreference(new_pref_path) != NULL); | 52 pref_service->FindPreference(new_pref_path) != NULL); |
46 PrefValueMap* pref_values; | 53 PrefValueMap* pref_values; |
47 if (i == extension_stack_.end()) { | 54 if (i == extension_stack_.end()) { |
48 pref_values = new PrefValueMap(); | 55 pref_values = new PrefValueMap(); |
49 if (is_registered_pref) | 56 if (is_registered_pref) |
50 (*pref_values)[new_pref_path] = new_pref_value; | 57 (*pref_values)[new_pref_path] = new_pref_value; |
51 | 58 |
52 ExtensionPrefs* extension_prefs = new ExtensionPrefs(extension, | 59 ExtensionPrefs* extension_prefs = new ExtensionPrefs(extension->id(), |
53 pref_values); | 60 pref_values); |
54 extension_stack_.push_front(extension_prefs); | 61 extension_stack_.push_front(extension_prefs); |
| 62 AddPrecedence(extension->id()); |
| 63 |
55 } else if (is_registered_pref) { | 64 } else if (is_registered_pref) { |
56 pref_values = (*i)->pref_values; | 65 pref_values = (*i)->pref_values; |
57 delete (*pref_values)[new_pref_path]; | 66 delete (*pref_values)[new_pref_path]; |
58 (*pref_values)[new_pref_path] = new_pref_value; | 67 (*pref_values)[new_pref_path] = new_pref_value; |
59 } | 68 } |
60 | 69 |
61 // Apply the preference to our local |prefs_| store. | 70 // Apply the preference to our local |prefs_| store. |
62 UpdateOnePref(new_pref_path); | 71 UpdateOnePref(new_pref_path); |
63 } | 72 } |
64 | 73 |
65 void ExtensionPrefStore::UninstallExtension(const Extension* extension) { | 74 void ExtensionPrefStore::UninstallExtension(const Extension* extension) { |
66 // Remove this extension from the stack. | 75 // Remove this extension from the stack. |
67 for (ExtensionStack::iterator i = extension_stack_.begin(); | 76 for (ExtensionStack::iterator i = extension_stack_.begin(); |
68 i != extension_stack_.end(); ++i) { | 77 i != extension_stack_.end(); ++i) { |
69 if ((*i)->extension == extension) { | 78 if ((*i)->extension_id == extension->id()) { |
70 scoped_ptr<ExtensionPrefs> to_be_deleted(*i); | 79 scoped_ptr<ExtensionPrefs> to_be_deleted(*i); |
71 extension_stack_.erase(i); | 80 extension_stack_.erase(i); |
| 81 RemovePrecedence(to_be_deleted->extension_id); |
72 UpdatePrefs(to_be_deleted->pref_values); | 82 UpdatePrefs(to_be_deleted->pref_values); |
73 return; | 83 return; |
74 } | 84 } |
75 } | 85 } |
76 } | 86 } |
77 | 87 |
78 void ExtensionPrefStore::GetExtensionIDs(std::vector<std::string>* result) { | 88 void ExtensionPrefStore::GetExtensionIDs(std::vector<std::string>* result) { |
79 for (ExtensionStack::iterator i = extension_stack_.begin(); | 89 for (ExtensionStack::iterator i = extension_stack_.begin(); |
80 i != extension_stack_.end(); ++i) { | 90 i != extension_stack_.end(); ++i) { |
81 (*result).push_back((*i)->extension->id()); | 91 (*result).push_back((*i)->extension_id); |
82 } | 92 } |
83 } | 93 } |
84 | 94 |
85 // This could be sped up by keeping track of which extension currently controls | 95 // This could be sped up by keeping track of which extension currently controls |
86 // a given preference, among other optimizations. But probably fewer than 10 | 96 // a given preference, among other optimizations. But probably fewer than 10 |
87 // installed extensions will be trying to control any preferences, so stick | 97 // installed extensions will be trying to control any preferences, so stick |
88 // with this simpler algorithm until it causes a problem. | 98 // with this simpler algorithm until it causes a problem. |
89 void ExtensionPrefStore::UpdateOnePref(const char* path) { | 99 void ExtensionPrefStore::UpdateOnePref(const char* path) { |
90 PrefService* pref_service = GetPrefService(); | 100 PrefService* pref_service = GetPrefService(); |
91 | 101 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 if (profile_ == NULL || profile_ == extension_profile) | 193 if (profile_ == NULL || profile_ == extension_profile) |
184 UninstallExtension(extension); | 194 UninstallExtension(extension); |
185 break; | 195 break; |
186 } | 196 } |
187 default: { | 197 default: { |
188 NOTREACHED(); | 198 NOTREACHED(); |
189 } | 199 } |
190 } | 200 } |
191 } | 201 } |
192 | 202 |
193 ExtensionPrefStore::ExtensionPrefs::ExtensionPrefs(const Extension* extension, | 203 void ExtensionPrefStore::AddPrecedence(const std::string& extension_id) { |
194 PrefValueMap* values) : extension(extension), pref_values(values) {} | 204 std::vector<std::string> precedence; |
| 205 GetExtensionPrecedences(&precedence); |
| 206 |
| 207 bool already_present = |
| 208 find(precedence.begin(), precedence.end(), extension_id) != |
| 209 precedence.end(); |
| 210 DCHECK(!already_present) << "Precedence for extension " << extension_id |
| 211 << " was already registered"; |
| 212 |
| 213 precedence.push_back(extension_id); |
| 214 PersistExtensionPrecedences(precedence); |
| 215 } |
| 216 |
| 217 void ExtensionPrefStore::RemovePrecedence(const std::string& extension_id) { |
| 218 std::vector<std::string> precedence; |
| 219 GetExtensionPrecedences(&precedence); |
| 220 std::vector<std::string>::iterator i = |
| 221 find(precedence.begin(), precedence.end(), extension_id); |
| 222 if (i != precedence.end()) |
| 223 precedence.erase(i); |
| 224 PersistExtensionPrecedences(precedence); |
| 225 } |
| 226 |
| 227 void ExtensionPrefStore::LazyInit() { |
| 228 DCHECK(extension_stack_.empty()) |
| 229 << "LazyInit called even though extension_stack_ is already initialized"; |
| 230 |
| 231 std::vector<std::string> precedence; |
| 232 GetExtensionPrecedences(&precedence); |
| 233 std::vector<std::string>::const_iterator i; |
| 234 for (i = precedence.begin(); i != precedence.end(); ++i) { |
| 235 ExtensionPrefs* extension_prefs = |
| 236 new ExtensionPrefs(*i, new PrefValueMap()); |
| 237 extension_stack_.push_front(extension_prefs); |
| 238 } |
| 239 } |
| 240 |
| 241 void ExtensionPrefStore::PersistExtensionPrecedences( |
| 242 const std::vector<std::string>& precedence) { |
| 243 DCHECK(profile_); |
| 244 DCHECK(profile_->GetExtensionsService()); |
| 245 DCHECK(profile_->GetExtensionsService()->extension_prefs()); |
| 246 ::ExtensionPrefs* extension_prefs = |
| 247 profile_->GetExtensionsService()->extension_prefs(); |
| 248 extension_prefs->PersistExtensionPrecedences(precedence); |
| 249 } |
| 250 |
| 251 void ExtensionPrefStore::GetExtensionPrecedences( |
| 252 std::vector<std::string>* precedence) const { |
| 253 DCHECK(profile_); |
| 254 DCHECK(profile_->GetExtensionsService()); |
| 255 DCHECK(profile_->GetExtensionsService()->extension_prefs()); |
| 256 ::ExtensionPrefs* extension_prefs = |
| 257 profile_->GetExtensionsService()->extension_prefs(); |
| 258 extension_prefs->GetExtensionPrecedences(precedence); |
| 259 } |
| 260 |
| 261 ExtensionPrefStore::ExtensionPrefs::ExtensionPrefs( |
| 262 const std::string& extension_id, PrefValueMap* values) |
| 263 : extension_id(extension_id), pref_values(values) {} |
195 | 264 |
196 ExtensionPrefStore::ExtensionPrefs::~ExtensionPrefs() { | 265 ExtensionPrefStore::ExtensionPrefs::~ExtensionPrefs() { |
197 STLDeleteValues(pref_values); | 266 STLDeleteValues(pref_values); |
198 delete pref_values; | 267 delete pref_values; |
199 } | 268 } |
OLD | NEW |