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

Side by Side Diff: chrome/browser/extensions/extension_pref_store.cc

Issue 4551001: Disable ExtensionPrefStore for local-state pref store (Closed) Base URL: http://git.chromium.org/git/chromium.git/@trunk
Patch Set: Addressed Pam's comments Created 10 years, 1 month 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
« no previous file with comments | « chrome/browser/extensions/extension_pref_store.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/extensions/extension_pref_store.h" 5 #include "chrome/browser/extensions/extension_pref_store.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/values.h" 10 #include "base/values.h"
11 #include "chrome/browser/browser_process.h" 11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/extensions/extensions_service.h" 12 #include "chrome/browser/extensions/extensions_service.h"
13 #include "chrome/browser/extensions/extension_prefs.h" 13 #include "chrome/browser/extensions/extension_prefs.h"
14 #include "chrome/browser/prefs/pref_service.h" 14 #include "chrome/browser/prefs/pref_service.h"
15 #include "chrome/browser/profile.h" 15 #include "chrome/browser/profile.h"
16 #include "chrome/common/extensions/extension.h" 16 #include "chrome/common/extensions/extension.h"
17 #include "chrome/common/notification_service.h" 17 #include "chrome/common/notification_details.h"
18 #include "chrome/common/notification_source.h"
19 #include "chrome/common/notification_type.h"
18 20
19 ExtensionPrefStore::ExtensionPrefStore(Profile* profile, 21 ExtensionPrefStore::ExtensionPrefStore(Profile* profile,
20 PrefNotifier::PrefStoreType type) 22 PrefNotifier::PrefStoreType type)
21 : prefs_(new DictionaryValue()), 23 : prefs_(new DictionaryValue()),
22 profile_(profile), 24 profile_(profile),
23 type_(type) { 25 type_(type) {
24 RegisterObservers(); 26 RegisterObservers();
25 } 27 }
26 28
27 ExtensionPrefStore::~ExtensionPrefStore() { 29 ExtensionPrefStore::~ExtensionPrefStore() {
28 STLDeleteElements(&extension_stack_); 30 STLDeleteElements(&extension_stack_);
29 notification_registrar_.RemoveAll(); 31 notification_registrar_.RemoveAll();
30 } 32 }
31 33
32 void ExtensionPrefStore::InstallExtensionPref(const Extension* extension, 34 void ExtensionPrefStore::InstallExtensionPref(const Extension* extension,
33 const char* new_pref_path, 35 const char* new_pref_path,
34 Value* new_pref_value) { 36 Value* new_pref_value) {
35 if (extension_stack_.empty()) 37 if (extension_stack_.empty())
36 LazyInit(); 38 LazyInit();
37 39
38 ExtensionStack::iterator i; 40 ExtensionStack::iterator i;
39 for (i = extension_stack_.begin(); i != extension_stack_.end(); ++i) { 41 for (i = extension_stack_.begin(); i != extension_stack_.end(); ++i) {
40 if ((*i)->extension_id == extension->id()) 42 if ((*i)->extension_id == extension->id())
41 break; 43 break;
42 } 44 }
43 45
44 // If this extension is not already in the stack, add it. Otherwise, update 46 // If this extension is not already in the stack, add it. Otherwise, update
45 // or add the value of this preference, but don't change the extension's 47 // or add the value of this preference, but don't change the extension's
46 // position in the stack. We store the extension even if this preference 48 // position in the stack.
47 // isn't registered with our PrefService, so that the ordering of extensions
48 // is consistent among all local-state and user ExtensionPrefStores.
49 PrefService* pref_service = GetPrefService();
50 // The pref_service may be NULL in unit testing.
51 bool is_registered_pref = (pref_service == NULL ||
52 pref_service->FindPreference(new_pref_path) != NULL);
53 PrefValueMap* pref_values;
54 if (i == extension_stack_.end()) { 49 if (i == extension_stack_.end()) {
55 pref_values = new PrefValueMap(); 50 PrefValueMap* pref_values = new PrefValueMap();
56 if (is_registered_pref) 51 (*pref_values)[new_pref_path] = new_pref_value;
57 (*pref_values)[new_pref_path] = new_pref_value;
58 52
59 ExtensionPrefs* extension_prefs = new ExtensionPrefs(extension->id(), 53 ExtensionPrefs* extension_prefs = new ExtensionPrefs(extension->id(),
60 pref_values); 54 pref_values);
61 extension_stack_.push_front(extension_prefs); 55 extension_stack_.push_front(extension_prefs);
62 AddPrecedence(extension->id()); 56 AddPrecedence(extension->id());
63 57
64 } else if (is_registered_pref) { 58 } else {
65 pref_values = (*i)->pref_values; 59 PrefValueMap* pref_values = (*i)->pref_values;
66 delete (*pref_values)[new_pref_path]; 60 delete (*pref_values)[new_pref_path];
67 (*pref_values)[new_pref_path] = new_pref_value; 61 (*pref_values)[new_pref_path] = new_pref_value;
68 } 62 }
69 63
70 // Apply the preference to our local |prefs_| store. 64 // Apply the preference to our local |prefs_| store.
71 UpdateOnePref(new_pref_path); 65 UpdateOnePref(new_pref_path);
72 } 66 }
73 67
74 void ExtensionPrefStore::UninstallExtension(const Extension* extension) { 68 void ExtensionPrefStore::UninstallExtension(const Extension* extension) {
75 // Remove this extension from the stack. 69 // Remove this extension from the stack.
(...skipping 14 matching lines...) Expand all
90 i != extension_stack_.end(); ++i) { 84 i != extension_stack_.end(); ++i) {
91 (*result).push_back((*i)->extension_id); 85 (*result).push_back((*i)->extension_id);
92 } 86 }
93 } 87 }
94 88
95 // This could be sped up by keeping track of which extension currently controls 89 // This could be sped up by keeping track of which extension currently controls
96 // a given preference, among other optimizations. But probably fewer than 10 90 // a given preference, among other optimizations. But probably fewer than 10
97 // installed extensions will be trying to control any preferences, so stick 91 // installed extensions will be trying to control any preferences, so stick
98 // with this simpler algorithm until it causes a problem. 92 // with this simpler algorithm until it causes a problem.
99 void ExtensionPrefStore::UpdateOnePref(const char* path) { 93 void ExtensionPrefStore::UpdateOnePref(const char* path) {
100 PrefService* pref_service = GetPrefService();
101
102 // There are at least two PrefServices, one for local state and one for
103 // user prefs. (See browser_main.cc.) Different preferences are registered
104 // in each; if this one doesn't have the desired pref registered, we ignore
105 // it and let the other one handle it.
106 // The pref_service may be NULL in unit testing.
107 if (pref_service && !pref_service->FindPreference(path))
108 return;
109
110 // Save the old value before removing it from the local cache. 94 // Save the old value before removing it from the local cache.
111 Value* my_old_value_ptr = NULL; 95 Value* my_old_value_ptr = NULL;
112 prefs_->Get(path, &my_old_value_ptr); 96 prefs_->Get(path, &my_old_value_ptr);
113 scoped_ptr<Value> my_old_value; 97 scoped_ptr<Value> my_old_value;
114 if (my_old_value_ptr) 98 if (my_old_value_ptr)
115 my_old_value.reset(my_old_value_ptr->DeepCopy()); 99 my_old_value.reset(my_old_value_ptr->DeepCopy());
116 100
117 // DictionaryValue::Set complains if a key is overwritten with the same 101 // DictionaryValue::Set complains if a key is overwritten with the same
118 // value, so remove it first. 102 // value, so remove it first.
119 prefs_->Remove(path, NULL); 103 prefs_->Remove(path, NULL);
120 104
121 // Find the first extension that wants to set this pref and use its value. 105 // Find the first extension that wants to set this pref and use its value.
122 Value* my_new_value = NULL; 106 Value* my_new_value = NULL;
123 for (ExtensionStack::iterator ext_iter = extension_stack_.begin(); 107 for (ExtensionStack::iterator ext_iter = extension_stack_.begin();
124 ext_iter != extension_stack_.end(); ++ext_iter) { 108 ext_iter != extension_stack_.end(); ++ext_iter) {
125 PrefValueMap::iterator value_iter = (*ext_iter)->pref_values->find(path); 109 PrefValueMap::iterator value_iter = (*ext_iter)->pref_values->find(path);
126 if (value_iter != (*ext_iter)->pref_values->end()) { 110 if (value_iter != (*ext_iter)->pref_values->end()) {
127 prefs_->Set(path, (*value_iter).second->DeepCopy()); 111 prefs_->Set(path, (*value_iter).second->DeepCopy());
128 my_new_value = (*value_iter).second; 112 my_new_value = (*value_iter).second;
129 break; 113 break;
130 } 114 }
131 } 115 }
132 116
117 // May be null in unit tests.
118 PrefService* pref_service = GetPrefService();
133 if (pref_service) { 119 if (pref_service) {
134 bool value_changed = true; 120 bool value_changed = true;
135 if (!my_old_value.get() && !my_new_value) { 121 if (!my_old_value.get() && !my_new_value) {
136 value_changed = false; 122 value_changed = false;
137 } else if (my_old_value.get() && 123 } else if (my_old_value.get() &&
138 my_new_value && 124 my_new_value &&
139 my_old_value->Equals(my_new_value)) { 125 my_old_value->Equals(my_new_value)) {
140 value_changed = false; 126 value_changed = false;
141 } 127 }
142 128
143 if (value_changed) 129 if (value_changed)
144 pref_service->pref_notifier()->OnPreferenceSet(path, type_); 130 pref_service->pref_notifier()->OnPreferenceSet(path, type_);
145 } 131 }
146 } 132 }
147 133
148 void ExtensionPrefStore::UpdatePrefs(const PrefValueMap* pref_values) { 134 void ExtensionPrefStore::UpdatePrefs(const PrefValueMap* pref_values) {
149 if (!pref_values) 135 if (!pref_values)
150 return; 136 return;
151 137
152 for (PrefValueMap::const_iterator i = pref_values->begin(); 138 for (PrefValueMap::const_iterator i = pref_values->begin();
153 i != pref_values->end(); ++i) { 139 i != pref_values->end(); ++i) {
154 UpdateOnePref(i->first); 140 UpdateOnePref(i->first);
155 } 141 }
156 } 142 }
157 143
158 PrefService* ExtensionPrefStore::GetPrefService() { 144 PrefService* ExtensionPrefStore::GetPrefService() {
159 if (profile_) 145 // May be null in unit tests.
160 return profile_->GetPrefs(); 146 if (!profile_)
161 return g_browser_process->local_state(); 147 return NULL;
148 return profile_->GetPrefs();
162 } 149 }
163 150
164 void ExtensionPrefStore::RegisterObservers() { 151 void ExtensionPrefStore::RegisterObservers() {
152 // If profile_==NULL, this ExtensionPrefStore is for local-state.
153 if (!profile_)
154 return;
155
165 notification_registrar_.Add(this, 156 notification_registrar_.Add(this,
166 NotificationType::EXTENSION_PREF_CHANGED, 157 NotificationType::EXTENSION_PREF_CHANGED,
167 NotificationService::AllSources()); 158 Source<Profile>(profile_));
168 159
169 notification_registrar_.Add(this, 160 notification_registrar_.Add(this,
170 NotificationType::EXTENSION_UNLOADED, 161 NotificationType::EXTENSION_UNLOADED,
171 NotificationService::AllSources()); 162 Source<Profile>(profile_));
172 } 163 }
173 164
174 void ExtensionPrefStore::Observe(NotificationType type, 165 void ExtensionPrefStore::Observe(NotificationType type,
175 const NotificationSource& source, 166 const NotificationSource& source,
176 const NotificationDetails& details) { 167 const NotificationDetails& details) {
177 switch (type.value) { 168 switch (type.value) {
178 case NotificationType::EXTENSION_PREF_CHANGED: { 169 case NotificationType::EXTENSION_PREF_CHANGED: {
179 Profile* extension_profile = Source<Profile>(source).ptr(); 170 ExtensionPrefStore::ExtensionPrefDetails* data =
180 // The ExtensionPrefStore for the local state watches all profiles. 171 Details<ExtensionPrefStore::ExtensionPrefDetails>(details).ptr();
181 if (!profile_ || profile_ == extension_profile) { 172 InstallExtensionPref(data->first, data->second.first,
182 ExtensionPrefStore::ExtensionPrefDetails* data = 173 data->second.second);
183 Details<ExtensionPrefStore::ExtensionPrefDetails>(details).ptr();
184 InstallExtensionPref(data->first, data->second.first,
185 data->second.second);
186 }
187 break; 174 break;
188 } 175 }
189 case NotificationType::EXTENSION_UNLOADED: { 176 case NotificationType::EXTENSION_UNLOADED: {
190 Profile* extension_profile = Source<Profile>(source).ptr();
191 const Extension* extension = Details<const Extension>(details).ptr(); 177 const Extension* extension = Details<const Extension>(details).ptr();
192 // The ExtensionPrefStore for the local state watches all profiles. 178 UninstallExtension(extension);
193 if (profile_ == NULL || profile_ == extension_profile)
194 UninstallExtension(extension);
195 break; 179 break;
196 } 180 }
197 default: { 181 default: {
198 NOTREACHED(); 182 NOTREACHED();
199 } 183 }
200 } 184 }
201 } 185 }
202 186
203 void ExtensionPrefStore::AddPrecedence(const std::string& extension_id) { 187 void ExtensionPrefStore::AddPrecedence(const std::string& extension_id) {
204 std::vector<std::string> precedence; 188 std::vector<std::string> precedence;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 243 }
260 244
261 ExtensionPrefStore::ExtensionPrefs::ExtensionPrefs( 245 ExtensionPrefStore::ExtensionPrefs::ExtensionPrefs(
262 const std::string& extension_id, PrefValueMap* values) 246 const std::string& extension_id, PrefValueMap* values)
263 : extension_id(extension_id), pref_values(values) {} 247 : extension_id(extension_id), pref_values(values) {}
264 248
265 ExtensionPrefStore::ExtensionPrefs::~ExtensionPrefs() { 249 ExtensionPrefStore::ExtensionPrefs::~ExtensionPrefs() {
266 STLDeleteValues(pref_values); 250 STLDeleteValues(pref_values);
267 delete pref_values; 251 delete pref_values;
268 } 252 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_pref_store.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698