Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_pref_value_map.cc
blobbcc4380ca9c26a401fa57eebe33cf754858ff8f1
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/extensions/extension_pref_value_map.h"
7 #include "base/prefs/pref_value_map.h"
8 #include "base/stl_util.h"
9 #include "base/values.h"
11 using extensions::ExtensionPrefsScope;
13 struct ExtensionPrefValueMap::ExtensionEntry {
14 // Installation time of the extension.
15 base::Time install_time;
16 // Whether extension is enabled in the profile.
17 bool enabled;
18 // Extension controlled preferences for the regular profile.
19 PrefValueMap regular_profile_preferences;
20 // Extension controlled preferences that should *only* apply to the regular
21 // profile.
22 PrefValueMap regular_only_profile_preferences;
23 // Persistent extension controlled preferences for the incognito profile,
24 // empty for regular profile ExtensionPrefStore.
25 PrefValueMap incognito_profile_preferences_persistent;
26 // Session only extension controlled preferences for the incognito profile.
27 // These preferences are deleted when the incognito profile is destroyed.
28 PrefValueMap incognito_profile_preferences_session_only;
31 ExtensionPrefValueMap::ExtensionPrefValueMap() : destroyed_(false) {
34 ExtensionPrefValueMap::~ExtensionPrefValueMap() {
35 if (!destroyed_) {
36 NotifyOfDestruction();
37 destroyed_ = true;
39 STLDeleteValues(&entries_);
40 entries_.clear();
43 void ExtensionPrefValueMap::Shutdown() {
44 NotifyOfDestruction();
45 destroyed_ = true;
48 void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
49 const std::string& key,
50 ExtensionPrefsScope scope,
51 base::Value* value) {
52 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
54 if (prefs->SetValue(key, value))
55 NotifyPrefValueChanged(key);
58 void ExtensionPrefValueMap::RemoveExtensionPref(
59 const std::string& ext_id,
60 const std::string& key,
61 ExtensionPrefsScope scope) {
62 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
63 if (prefs->RemoveValue(key))
64 NotifyPrefValueChanged(key);
67 bool ExtensionPrefValueMap::CanExtensionControlPref(
68 const std::string& extension_id,
69 const std::string& pref_key,
70 bool incognito) const {
71 ExtensionEntryMap::const_iterator ext = entries_.find(extension_id);
72 if (ext == entries_.end()) {
73 NOTREACHED();
74 return false;
77 ExtensionEntryMap::const_iterator winner =
78 GetEffectivePrefValueController(pref_key, incognito, NULL);
79 if (winner == entries_.end())
80 return true;
82 return winner->second->install_time <= ext->second->install_time;
85 void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() {
86 typedef std::set<std::string> KeySet;
87 KeySet deleted_keys;
89 ExtensionEntryMap::iterator i;
90 for (i = entries_.begin(); i != entries_.end(); ++i) {
91 PrefValueMap& inc_prefs =
92 i->second->incognito_profile_preferences_session_only;
93 PrefValueMap::iterator j;
94 for (j = inc_prefs.begin(); j != inc_prefs.end(); ++j)
95 deleted_keys.insert(j->first);
96 inc_prefs.Clear();
99 KeySet::iterator k;
100 for (k = deleted_keys.begin(); k != deleted_keys.end(); ++k)
101 NotifyPrefValueChanged(*k);
104 bool ExtensionPrefValueMap::DoesExtensionControlPref(
105 const std::string& extension_id,
106 const std::string& pref_key,
107 bool* from_incognito) const {
108 bool incognito = (from_incognito != NULL);
109 ExtensionEntryMap::const_iterator winner =
110 GetEffectivePrefValueController(pref_key, incognito, from_incognito);
111 if (winner == entries_.end())
112 return false;
113 return winner->first == extension_id;
116 void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
117 const base::Time& install_time,
118 bool is_enabled) {
119 if (entries_.find(ext_id) == entries_.end()) {
120 entries_[ext_id] = new ExtensionEntry;
122 // Only update the install time if the extension is newly installed.
123 entries_[ext_id]->install_time = install_time;
126 entries_[ext_id]->enabled = is_enabled;
129 void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
130 ExtensionEntryMap::iterator i = entries_.find(ext_id);
131 if (i == entries_.end())
132 return;
133 std::set<std::string> keys; // keys set by this extension
134 GetExtensionControlledKeys(*(i->second), &keys);
136 delete i->second;
137 entries_.erase(i);
139 NotifyPrefValueChanged(keys);
142 void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
143 bool is_enabled) {
144 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
145 // This may happen when sync sets the extension state for an
146 // extension that is not installed.
147 if (i == entries_.end())
148 return;
149 if (i->second->enabled == is_enabled)
150 return;
151 std::set<std::string> keys; // keys set by this extension
152 GetExtensionControlledKeys(*(i->second), &keys);
153 i->second->enabled = is_enabled;
154 NotifyPrefValueChanged(keys);
157 PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
158 const std::string& ext_id,
159 ExtensionPrefsScope scope) {
160 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
161 CHECK(i != entries_.end());
162 switch (scope) {
163 case extensions::kExtensionPrefsScopeRegular:
164 return &(i->second->regular_profile_preferences);
165 case extensions::kExtensionPrefsScopeRegularOnly:
166 return &(i->second->regular_only_profile_preferences);
167 case extensions::kExtensionPrefsScopeIncognitoPersistent:
168 return &(i->second->incognito_profile_preferences_persistent);
169 case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
170 return &(i->second->incognito_profile_preferences_session_only);
172 NOTREACHED();
173 return NULL;
176 const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
177 const std::string& ext_id,
178 ExtensionPrefsScope scope) const {
179 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
180 CHECK(i != entries_.end());
181 switch (scope) {
182 case extensions::kExtensionPrefsScopeRegular:
183 return &(i->second->regular_profile_preferences);
184 case extensions::kExtensionPrefsScopeRegularOnly:
185 return &(i->second->regular_only_profile_preferences);
186 case extensions::kExtensionPrefsScopeIncognitoPersistent:
187 return &(i->second->incognito_profile_preferences_persistent);
188 case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
189 return &(i->second->incognito_profile_preferences_session_only);
191 NOTREACHED();
192 return NULL;
195 void ExtensionPrefValueMap::GetExtensionControlledKeys(
196 const ExtensionEntry& entry,
197 std::set<std::string>* out) const {
198 PrefValueMap::const_iterator i;
200 const PrefValueMap& regular_prefs = entry.regular_profile_preferences;
201 for (i = regular_prefs.begin(); i != regular_prefs.end(); ++i)
202 out->insert(i->first);
204 const PrefValueMap& regular_only_prefs =
205 entry.regular_only_profile_preferences;
206 for (i = regular_only_prefs.begin(); i != regular_only_prefs.end(); ++i)
207 out->insert(i->first);
209 const PrefValueMap& inc_prefs_pers =
210 entry.incognito_profile_preferences_persistent;
211 for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i)
212 out->insert(i->first);
214 const PrefValueMap& inc_prefs_session =
215 entry.incognito_profile_preferences_session_only;
216 for (i = inc_prefs_session.begin(); i != inc_prefs_session.end(); ++i)
217 out->insert(i->first);
220 const base::Value* ExtensionPrefValueMap::GetEffectivePrefValue(
221 const std::string& key,
222 bool incognito,
223 bool* from_incognito) const {
224 ExtensionEntryMap::const_iterator winner =
225 GetEffectivePrefValueController(key, incognito, from_incognito);
226 if (winner == entries_.end())
227 return NULL;
229 const base::Value* value = NULL;
230 const std::string& ext_id = winner->first;
232 // First search for incognito session only preferences.
233 if (incognito) {
234 const PrefValueMap* prefs = GetExtensionPrefValueMap(
235 ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
236 prefs->GetValue(key, &value);
237 if (value)
238 return value;
240 // If no incognito session only preference exists, fall back to persistent
241 // incognito preference.
242 prefs = GetExtensionPrefValueMap(
243 ext_id,
244 extensions::kExtensionPrefsScopeIncognitoPersistent);
245 prefs->GetValue(key, &value);
246 if (value)
247 return value;
248 } else {
249 // Regular-only preference.
250 const PrefValueMap* prefs = GetExtensionPrefValueMap(
251 ext_id, extensions::kExtensionPrefsScopeRegularOnly);
252 prefs->GetValue(key, &value);
253 if (value)
254 return value;
257 // Regular preference.
258 const PrefValueMap* prefs = GetExtensionPrefValueMap(
259 ext_id, extensions::kExtensionPrefsScopeRegular);
260 prefs->GetValue(key, &value);
261 return value;
264 ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
265 ExtensionPrefValueMap::GetEffectivePrefValueController(
266 const std::string& key,
267 bool incognito,
268 bool* from_incognito) const {
269 ExtensionEntryMap::const_iterator winner = entries_.end();
270 base::Time winners_install_time;
272 ExtensionEntryMap::const_iterator i;
273 for (i = entries_.begin(); i != entries_.end(); ++i) {
274 const std::string& ext_id = i->first;
275 const base::Time& install_time = i->second->install_time;
276 const bool enabled = i->second->enabled;
278 if (!enabled)
279 continue;
280 if (install_time < winners_install_time)
281 continue;
283 const base::Value* value = NULL;
284 const PrefValueMap* prefs = GetExtensionPrefValueMap(
285 ext_id, extensions::kExtensionPrefsScopeRegular);
286 if (prefs->GetValue(key, &value)) {
287 winner = i;
288 winners_install_time = install_time;
289 if (from_incognito)
290 *from_incognito = false;
293 if (!incognito) {
294 const PrefValueMap* prefs = GetExtensionPrefValueMap(
295 ext_id, extensions::kExtensionPrefsScopeRegularOnly);
296 if (prefs->GetValue(key, &value)) {
297 winner = i;
298 winners_install_time = install_time;
299 if (from_incognito)
300 *from_incognito = false;
302 // Ignore the following prefs, because they're incognito-only.
303 continue;
306 prefs = GetExtensionPrefValueMap(
307 ext_id, extensions::kExtensionPrefsScopeIncognitoPersistent);
308 if (prefs->GetValue(key, &value)) {
309 winner = i;
310 winners_install_time = install_time;
311 if (from_incognito)
312 *from_incognito = true;
315 prefs = GetExtensionPrefValueMap(
316 ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
317 if (prefs->GetValue(key, &value)) {
318 winner = i;
319 winners_install_time = install_time;
320 if (from_incognito)
321 *from_incognito = true;
324 return winner;
327 void ExtensionPrefValueMap::AddObserver(
328 ExtensionPrefValueMap::Observer* observer) {
329 observers_.AddObserver(observer);
331 // Collect all currently used keys and notify the new observer.
332 std::set<std::string> keys;
333 ExtensionEntryMap::const_iterator i;
334 for (i = entries_.begin(); i != entries_.end(); ++i)
335 GetExtensionControlledKeys(*(i->second), &keys);
337 std::set<std::string>::const_iterator j;
338 for (j = keys.begin(); j != keys.end(); ++j)
339 observer->OnPrefValueChanged(*j);
342 void ExtensionPrefValueMap::RemoveObserver(
343 ExtensionPrefValueMap::Observer* observer) {
344 observers_.RemoveObserver(observer);
347 std::string ExtensionPrefValueMap::GetExtensionControllingPref(
348 const std::string& pref_key) const {
349 ExtensionEntryMap::const_iterator winner =
350 GetEffectivePrefValueController(pref_key, false, NULL);
351 if (winner == entries_.end())
352 return std::string();
353 return winner->first;
356 void ExtensionPrefValueMap::NotifyInitializationCompleted() {
357 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
358 OnInitializationCompleted());
361 void ExtensionPrefValueMap::NotifyPrefValueChanged(
362 const std::set<std::string>& keys) {
363 std::set<std::string>::const_iterator i;
364 for (i = keys.begin(); i != keys.end(); ++i)
365 NotifyPrefValueChanged(*i);
368 void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
369 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
370 OnPrefValueChanged(key));
373 void ExtensionPrefValueMap::NotifyOfDestruction() {
374 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
375 OnExtensionPrefValueMapDestruction());