blob: 4d9877a6655842489d49cee190b71d744d95b969 [file] [log] [blame]
[email protected]ef9bba12012-04-06 16:26:091// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]9a8c4022011-01-25 14:25:332// 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_value_map.h"
6
[email protected]7286e3fc2011-07-19 22:13:247#include "base/stl_util.h"
[email protected]9a8c4022011-01-25 14:25:338#include "base/values.h"
9#include "chrome/browser/prefs/pref_value_map.h"
10
[email protected]0865c1342011-01-28 20:29:3711struct ExtensionPrefValueMap::ExtensionEntry {
12 // Installation time of the extension.
13 base::Time install_time;
14 // Whether extension is enabled in the profile.
15 bool enabled;
[email protected]9783c162011-05-25 21:45:5116 // Extension controlled preferences for the regular profile.
17 PrefValueMap regular_profile_preferences;
18 // Persistent extension controlled preferences for the incognito profile,
19 // empty for regular profile ExtensionPrefStore.
20 PrefValueMap incognito_profile_preferences_persistent;
[email protected]31685742011-05-25 23:01:5621 // Session only extension controlled preferences for the incognito profile.
22 // These preferences are deleted when the incognito profile is destroyed.
23 PrefValueMap incognito_profile_preferences_session_only;
[email protected]0865c1342011-01-28 20:29:3724};
25
[email protected]ef9bba12012-04-06 16:26:0926ExtensionPrefValueMap::ExtensionPrefValueMap() : destroyed_(false) {
[email protected]9a8c4022011-01-25 14:25:3327}
28
29ExtensionPrefValueMap::~ExtensionPrefValueMap() {
[email protected]ef9bba12012-04-06 16:26:0930 if (!destroyed_) {
31 NotifyOfDestruction();
32 destroyed_ = true;
33 }
[email protected]9a8c4022011-01-25 14:25:3334 STLDeleteValues(&entries_);
35 entries_.clear();
36}
37
[email protected]ef9bba12012-04-06 16:26:0938void ExtensionPrefValueMap::Shutdown() {
39 NotifyOfDestruction();
40 destroyed_ = true;
41}
42
[email protected]9a8c4022011-01-25 14:25:3343void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
44 const std::string& key,
[email protected]dece9a62011-06-07 17:38:5945 ExtensionPrefsScope scope,
[email protected]9a8c4022011-01-25 14:25:3346 Value* value) {
[email protected]9783c162011-05-25 21:45:5147 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
[email protected]9a8c4022011-01-25 14:25:3348
49 if (prefs->SetValue(key, value))
50 NotifyPrefValueChanged(key);
51}
52
[email protected]9783c162011-05-25 21:45:5153void ExtensionPrefValueMap::RemoveExtensionPref(
54 const std::string& ext_id,
55 const std::string& key,
[email protected]dece9a62011-06-07 17:38:5956 ExtensionPrefsScope scope) {
[email protected]9783c162011-05-25 21:45:5157 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
[email protected]9a8c4022011-01-25 14:25:3358 if (prefs->RemoveValue(key))
59 NotifyPrefValueChanged(key);
60}
61
[email protected]9a28f132011-02-24 21:15:1662bool ExtensionPrefValueMap::CanExtensionControlPref(
63 const std::string& extension_id,
64 const std::string& pref_key,
65 bool incognito) const {
66 ExtensionEntryMap::const_iterator ext = entries_.find(extension_id);
67 if (ext == entries_.end()) {
68 NOTREACHED();
69 return false;
70 }
71
72 ExtensionEntryMap::const_iterator winner =
[email protected]c0793562011-03-09 15:31:0373 GetEffectivePrefValueController(pref_key, incognito, NULL);
[email protected]9a28f132011-02-24 21:15:1674 if (winner == entries_.end())
75 return true;
76
77 return winner->second->install_time <= ext->second->install_time;
78}
79
[email protected]31685742011-05-25 23:01:5680void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() {
81 typedef std::set<std::string> KeySet;
82 KeySet deleted_keys;
83
84 ExtensionEntryMap::iterator i;
85 for (i = entries_.begin(); i != entries_.end(); ++i) {
86 PrefValueMap& inc_prefs =
87 i->second->incognito_profile_preferences_session_only;
88 PrefValueMap::iterator j;
89 for (j = inc_prefs.begin(); j != inc_prefs.end(); ++j)
90 deleted_keys.insert(j->first);
91 inc_prefs.Clear();
92 }
93
94 KeySet::iterator k;
95 for (k = deleted_keys.begin(); k != deleted_keys.end(); ++k)
96 NotifyPrefValueChanged(*k);
97}
98
[email protected]9a28f132011-02-24 21:15:1699bool ExtensionPrefValueMap::DoesExtensionControlPref(
100 const std::string& extension_id,
101 const std::string& pref_key,
102 bool incognito) const {
103 ExtensionEntryMap::const_iterator winner =
[email protected]c0793562011-03-09 15:31:03104 GetEffectivePrefValueController(pref_key, incognito, NULL);
[email protected]9a28f132011-02-24 21:15:16105 if (winner == entries_.end())
106 return false;
107 return winner->first == extension_id;
108}
109
[email protected]9a8c4022011-01-25 14:25:33110void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
111 const base::Time& install_time,
112 bool is_enabled) {
113 if (entries_.find(ext_id) != entries_.end())
114 UnregisterExtension(ext_id);
115 entries_[ext_id] = new ExtensionEntry;
116 entries_[ext_id]->install_time = install_time;
117 entries_[ext_id]->enabled = is_enabled;
118}
119
120void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
121 ExtensionEntryMap::iterator i = entries_.find(ext_id);
122 if (i == entries_.end())
123 return;
124 std::set<std::string> keys; // keys set by this extension
125 GetExtensionControlledKeys(*(i->second), &keys);
126
127 delete i->second;
128 entries_.erase(i);
129
130 NotifyPrefValueChanged(keys);
131}
132
133void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
134 bool is_enabled) {
135 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
[email protected]06f92562011-04-29 19:27:31136 // This may happen when sync sets the extension state for an
137 // extension that is not installed.
138 if (i == entries_.end())
139 return;
[email protected]9a8c4022011-01-25 14:25:33140 if (i->second->enabled == is_enabled)
141 return;
142 std::set<std::string> keys; // keys set by this extension
143 GetExtensionControlledKeys(*(i->second), &keys);
144 i->second->enabled = is_enabled;
145 NotifyPrefValueChanged(keys);
146}
147
148PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
149 const std::string& ext_id,
[email protected]dece9a62011-06-07 17:38:59150 ExtensionPrefsScope scope) {
[email protected]9a8c4022011-01-25 14:25:33151 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
152 CHECK(i != entries_.end());
[email protected]9783c162011-05-25 21:45:51153 switch (scope) {
[email protected]dece9a62011-06-07 17:38:59154 case kExtensionPrefsScopeRegular:
[email protected]9783c162011-05-25 21:45:51155 return &(i->second->regular_profile_preferences);
[email protected]dece9a62011-06-07 17:38:59156 case kExtensionPrefsScopeIncognitoPersistent:
[email protected]9783c162011-05-25 21:45:51157 return &(i->second->incognito_profile_preferences_persistent);
[email protected]dece9a62011-06-07 17:38:59158 case kExtensionPrefsScopeIncognitoSessionOnly:
[email protected]31685742011-05-25 23:01:56159 return &(i->second->incognito_profile_preferences_session_only);
[email protected]9783c162011-05-25 21:45:51160 }
161 NOTREACHED();
162 return NULL;
[email protected]9a8c4022011-01-25 14:25:33163}
164
165const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
166 const std::string& ext_id,
[email protected]dece9a62011-06-07 17:38:59167 ExtensionPrefsScope scope) const {
[email protected]9a8c4022011-01-25 14:25:33168 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
169 CHECK(i != entries_.end());
[email protected]9783c162011-05-25 21:45:51170 switch (scope) {
[email protected]dece9a62011-06-07 17:38:59171 case kExtensionPrefsScopeRegular:
[email protected]9783c162011-05-25 21:45:51172 return &(i->second->regular_profile_preferences);
[email protected]dece9a62011-06-07 17:38:59173 case kExtensionPrefsScopeIncognitoPersistent:
[email protected]9783c162011-05-25 21:45:51174 return &(i->second->incognito_profile_preferences_persistent);
[email protected]dece9a62011-06-07 17:38:59175 case kExtensionPrefsScopeIncognitoSessionOnly:
[email protected]31685742011-05-25 23:01:56176 return &(i->second->incognito_profile_preferences_session_only);
[email protected]9783c162011-05-25 21:45:51177 }
178 NOTREACHED();
179 return NULL;
[email protected]9a8c4022011-01-25 14:25:33180}
181
182void ExtensionPrefValueMap::GetExtensionControlledKeys(
183 const ExtensionEntry& entry,
184 std::set<std::string>* out) const {
185 PrefValueMap::const_iterator i;
186
[email protected]9783c162011-05-25 21:45:51187 const PrefValueMap& reg_prefs = entry.regular_profile_preferences;
[email protected]9a8c4022011-01-25 14:25:33188 for (i = reg_prefs.begin(); i != reg_prefs.end(); ++i)
189 out->insert(i->first);
190
[email protected]9783c162011-05-25 21:45:51191 const PrefValueMap& inc_prefs_pers =
192 entry.incognito_profile_preferences_persistent;
193 for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i)
[email protected]9a8c4022011-01-25 14:25:33194 out->insert(i->first);
[email protected]31685742011-05-25 23:01:56195
196 const PrefValueMap& inc_prefs_session =
197 entry.incognito_profile_preferences_session_only;
198 for (i = inc_prefs_session.begin(); i != inc_prefs_session.end(); ++i)
199 out->insert(i->first);
[email protected]9a8c4022011-01-25 14:25:33200}
201
202const Value* ExtensionPrefValueMap::GetEffectivePrefValue(
203 const std::string& key,
[email protected]c0793562011-03-09 15:31:03204 bool incognito,
205 bool* from_incognito) const {
[email protected]9a28f132011-02-24 21:15:16206 ExtensionEntryMap::const_iterator winner =
[email protected]c0793562011-03-09 15:31:03207 GetEffectivePrefValueController(key, incognito, from_incognito);
[email protected]9a28f132011-02-24 21:15:16208 if (winner == entries_.end())
209 return NULL;
210
[email protected]68bf41a2011-03-25 16:38:31211 const Value* value = NULL;
[email protected]9a28f132011-02-24 21:15:16212 const std::string& ext_id = winner->first;
[email protected]31685742011-05-25 23:01:56213
214 // First search for incognito session only preferences.
[email protected]9783c162011-05-25 21:45:51215 if (incognito) {
216 const PrefValueMap* prefs = GetExtensionPrefValueMap(
[email protected]dece9a62011-06-07 17:38:59217 ext_id, kExtensionPrefsScopeIncognitoSessionOnly);
[email protected]31685742011-05-25 23:01:56218 prefs->GetValue(key, &value);
219 }
220
221 // If no incognito session only preference exists, fall back to persistent
222 // incognito preference.
223 if (incognito && !value) {
224 const PrefValueMap* prefs = GetExtensionPrefValueMap(
[email protected]dece9a62011-06-07 17:38:59225 ext_id, kExtensionPrefsScopeIncognitoPersistent);
[email protected]9783c162011-05-25 21:45:51226 prefs->GetValue(key, &value);
227 }
[email protected]31685742011-05-25 23:01:56228
229 // Finally consider a regular preference.
[email protected]9783c162011-05-25 21:45:51230 if (!value) {
231 const PrefValueMap* prefs = GetExtensionPrefValueMap(
[email protected]dece9a62011-06-07 17:38:59232 ext_id, kExtensionPrefsScopeRegular);
[email protected]9783c162011-05-25 21:45:51233 prefs->GetValue(key, &value);
234 }
[email protected]9a28f132011-02-24 21:15:16235 return value;
236}
237
238ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
239ExtensionPrefValueMap::GetEffectivePrefValueController(
240 const std::string& key,
[email protected]c0793562011-03-09 15:31:03241 bool incognito,
242 bool* from_incognito) const {
[email protected]9a28f132011-02-24 21:15:16243 ExtensionEntryMap::const_iterator winner = entries_.end();
[email protected]9a8c4022011-01-25 14:25:33244 base::Time winners_install_time;
245
246 ExtensionEntryMap::const_iterator i;
247 for (i = entries_.begin(); i != entries_.end(); ++i) {
248 const std::string& ext_id = i->first;
249 const base::Time& install_time = i->second->install_time;
250 const bool enabled = i->second->enabled;
251
252 if (!enabled)
253 continue;
254 if (install_time < winners_install_time)
255 continue;
256
[email protected]68bf41a2011-03-25 16:38:31257 const Value* value = NULL;
[email protected]9783c162011-05-25 21:45:51258 const PrefValueMap* prefs = GetExtensionPrefValueMap(
[email protected]dece9a62011-06-07 17:38:59259 ext_id, kExtensionPrefsScopeRegular);
[email protected]9a8c4022011-01-25 14:25:33260 if (prefs->GetValue(key, &value)) {
[email protected]9a28f132011-02-24 21:15:16261 winner = i;
[email protected]9a8c4022011-01-25 14:25:33262 winners_install_time = install_time;
[email protected]c0793562011-03-09 15:31:03263 if (from_incognito)
264 *from_incognito = false;
[email protected]9a8c4022011-01-25 14:25:33265 }
266
267 if (!incognito)
268 continue;
269
[email protected]9783c162011-05-25 21:45:51270 prefs = GetExtensionPrefValueMap(
[email protected]dece9a62011-06-07 17:38:59271 ext_id, kExtensionPrefsScopeIncognitoPersistent);
[email protected]9a8c4022011-01-25 14:25:33272 if (prefs->GetValue(key, &value)) {
[email protected]9a28f132011-02-24 21:15:16273 winner = i;
[email protected]9a8c4022011-01-25 14:25:33274 winners_install_time = install_time;
[email protected]c0793562011-03-09 15:31:03275 if (from_incognito)
276 *from_incognito = true;
[email protected]9a8c4022011-01-25 14:25:33277 }
[email protected]31685742011-05-25 23:01:56278
279 prefs = GetExtensionPrefValueMap(
[email protected]dece9a62011-06-07 17:38:59280 ext_id, kExtensionPrefsScopeIncognitoSessionOnly);
[email protected]31685742011-05-25 23:01:56281 if (prefs->GetValue(key, &value)) {
282 winner = i;
283 winners_install_time = install_time;
284 if (from_incognito)
285 *from_incognito = true;
286 }
[email protected]9a8c4022011-01-25 14:25:33287 }
288 return winner;
289}
290
291void ExtensionPrefValueMap::AddObserver(
292 ExtensionPrefValueMap::Observer* observer) {
293 observers_.AddObserver(observer);
294
295 // Collect all currently used keys and notify the new observer.
296 std::set<std::string> keys;
297 ExtensionEntryMap::const_iterator i;
298 for (i = entries_.begin(); i != entries_.end(); ++i)
299 GetExtensionControlledKeys(*(i->second), &keys);
300
301 std::set<std::string>::const_iterator j;
302 for (j = keys.begin(); j != keys.end(); ++j)
303 observer->OnPrefValueChanged(*j);
304}
305
306void ExtensionPrefValueMap::RemoveObserver(
307 ExtensionPrefValueMap::Observer* observer) {
308 observers_.RemoveObserver(observer);
309}
310
311void ExtensionPrefValueMap::NotifyInitializationCompleted() {
312 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
313 OnInitializationCompleted());
314}
315
316void ExtensionPrefValueMap::NotifyPrefValueChanged(
317 const std::set<std::string>& keys) {
318 std::set<std::string>::const_iterator i;
319 for (i = keys.begin(); i != keys.end(); ++i)
320 NotifyPrefValueChanged(*i);
321}
322
323void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
324 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
325 OnPrefValueChanged(key));
326}
327
328void ExtensionPrefValueMap::NotifyOfDestruction() {
329 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
330 OnExtensionPrefValueMapDestruction());
331}