1 // Copyright (c) 2011 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_value_map.h"
6
7 #include "base/stl_util-inl.h"
8 #include "base/values.h"
9 #include "chrome/browser/prefs/pref_value_map.h"
10
11 struct ExtensionPrefValueMap::ExtensionEntry {
12 // Installation time of the extension.
13 base::Time install_time;
14 // Whether extension is enabled in the profile.
15 bool enabled;
16 // Regular preferences.
17 PrefValueMap reg_preferences;
18 // Incognito preferences, empty for regular ExtensionPrefStore.
19 PrefValueMap inc_preferences;
20 };
21
ExtensionPrefValueMap()22 ExtensionPrefValueMap::ExtensionPrefValueMap() {
23 }
24
~ExtensionPrefValueMap()25 ExtensionPrefValueMap::~ExtensionPrefValueMap() {
26 NotifyOfDestruction();
27 STLDeleteValues(&entries_);
28 entries_.clear();
29 }
30
SetExtensionPref(const std::string & ext_id,const std::string & key,bool incognito,Value * value)31 void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
32 const std::string& key,
33 bool incognito,
34 Value* value) {
35 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, incognito);
36
37 if (prefs->SetValue(key, value))
38 NotifyPrefValueChanged(key);
39 }
40
RemoveExtensionPref(const std::string & ext_id,const std::string & key,bool incognito)41 void ExtensionPrefValueMap::RemoveExtensionPref(const std::string& ext_id,
42 const std::string& key,
43 bool incognito) {
44 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, incognito);
45 if (prefs->RemoveValue(key))
46 NotifyPrefValueChanged(key);
47 }
48
CanExtensionControlPref(const std::string & extension_id,const std::string & pref_key,bool incognito) const49 bool ExtensionPrefValueMap::CanExtensionControlPref(
50 const std::string& extension_id,
51 const std::string& pref_key,
52 bool incognito) const {
53 ExtensionEntryMap::const_iterator ext = entries_.find(extension_id);
54 if (ext == entries_.end()) {
55 NOTREACHED();
56 return false;
57 }
58
59 ExtensionEntryMap::const_iterator winner =
60 GetEffectivePrefValueController(pref_key, incognito, NULL);
61 if (winner == entries_.end())
62 return true;
63
64 return winner->second->install_time <= ext->second->install_time;
65 }
66
DoesExtensionControlPref(const std::string & extension_id,const std::string & pref_key,bool incognito) const67 bool ExtensionPrefValueMap::DoesExtensionControlPref(
68 const std::string& extension_id,
69 const std::string& pref_key,
70 bool incognito) const {
71 ExtensionEntryMap::const_iterator winner =
72 GetEffectivePrefValueController(pref_key, incognito, NULL);
73 if (winner == entries_.end())
74 return false;
75 return winner->first == extension_id;
76 }
77
RegisterExtension(const std::string & ext_id,const base::Time & install_time,bool is_enabled)78 void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
79 const base::Time& install_time,
80 bool is_enabled) {
81 if (entries_.find(ext_id) != entries_.end())
82 UnregisterExtension(ext_id);
83 entries_[ext_id] = new ExtensionEntry;
84 entries_[ext_id]->install_time = install_time;
85 entries_[ext_id]->enabled = is_enabled;
86 }
87
UnregisterExtension(const std::string & ext_id)88 void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
89 ExtensionEntryMap::iterator i = entries_.find(ext_id);
90 if (i == entries_.end())
91 return;
92 std::set<std::string> keys; // keys set by this extension
93 GetExtensionControlledKeys(*(i->second), &keys);
94
95 delete i->second;
96 entries_.erase(i);
97
98 NotifyPrefValueChanged(keys);
99 }
100
SetExtensionState(const std::string & ext_id,bool is_enabled)101 void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
102 bool is_enabled) {
103 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
104 CHECK(i != entries_.end());
105 if (i->second->enabled == is_enabled)
106 return;
107 std::set<std::string> keys; // keys set by this extension
108 GetExtensionControlledKeys(*(i->second), &keys);
109 i->second->enabled = is_enabled;
110 NotifyPrefValueChanged(keys);
111 }
112
GetExtensionPrefValueMap(const std::string & ext_id,bool incognito)113 PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
114 const std::string& ext_id,
115 bool incognito) {
116 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
117 CHECK(i != entries_.end());
118 return incognito ? &(i->second->inc_preferences)
119 : &(i->second->reg_preferences);
120 }
121
GetExtensionPrefValueMap(const std::string & ext_id,bool incognito) const122 const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
123 const std::string& ext_id,
124 bool incognito) const {
125 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
126 CHECK(i != entries_.end());
127 return incognito ? &(i->second->inc_preferences)
128 : &(i->second->reg_preferences);
129 }
130
GetExtensionControlledKeys(const ExtensionEntry & entry,std::set<std::string> * out) const131 void ExtensionPrefValueMap::GetExtensionControlledKeys(
132 const ExtensionEntry& entry,
133 std::set<std::string>* out) const {
134 PrefValueMap::const_iterator i;
135
136 const PrefValueMap& reg_prefs = entry.reg_preferences;
137 for (i = reg_prefs.begin(); i != reg_prefs.end(); ++i)
138 out->insert(i->first);
139
140 const PrefValueMap& inc_prefs = entry.inc_preferences;
141 for (i = inc_prefs.begin(); i != inc_prefs.end(); ++i)
142 out->insert(i->first);
143 }
144
GetEffectivePrefValue(const std::string & key,bool incognito,bool * from_incognito) const145 const Value* ExtensionPrefValueMap::GetEffectivePrefValue(
146 const std::string& key,
147 bool incognito,
148 bool* from_incognito) const {
149 ExtensionEntryMap::const_iterator winner =
150 GetEffectivePrefValueController(key, incognito, from_incognito);
151 if (winner == entries_.end())
152 return NULL;
153
154 const Value* value = NULL;
155 const std::string& ext_id = winner->first;
156 if (incognito)
157 GetExtensionPrefValueMap(ext_id, true)->GetValue(key, &value);
158 if (!value)
159 GetExtensionPrefValueMap(ext_id, false)->GetValue(key, &value);
160 return value;
161 }
162
163 ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
GetEffectivePrefValueController(const std::string & key,bool incognito,bool * from_incognito) const164 ExtensionPrefValueMap::GetEffectivePrefValueController(
165 const std::string& key,
166 bool incognito,
167 bool* from_incognito) const {
168 ExtensionEntryMap::const_iterator winner = entries_.end();
169 base::Time winners_install_time;
170
171 ExtensionEntryMap::const_iterator i;
172 for (i = entries_.begin(); i != entries_.end(); ++i) {
173 const std::string& ext_id = i->first;
174 const base::Time& install_time = i->second->install_time;
175 const bool enabled = i->second->enabled;
176
177 if (!enabled)
178 continue;
179 if (install_time < winners_install_time)
180 continue;
181
182 const Value* value = NULL;
183 const PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, false);
184 if (prefs->GetValue(key, &value)) {
185 winner = i;
186 winners_install_time = install_time;
187 if (from_incognito)
188 *from_incognito = false;
189 }
190
191 if (!incognito)
192 continue;
193
194 prefs = GetExtensionPrefValueMap(ext_id, true);
195 if (prefs->GetValue(key, &value)) {
196 winner = i;
197 winners_install_time = install_time;
198 if (from_incognito)
199 *from_incognito = true;
200 }
201 }
202 return winner;
203 }
204
AddObserver(ExtensionPrefValueMap::Observer * observer)205 void ExtensionPrefValueMap::AddObserver(
206 ExtensionPrefValueMap::Observer* observer) {
207 observers_.AddObserver(observer);
208
209 // Collect all currently used keys and notify the new observer.
210 std::set<std::string> keys;
211 ExtensionEntryMap::const_iterator i;
212 for (i = entries_.begin(); i != entries_.end(); ++i)
213 GetExtensionControlledKeys(*(i->second), &keys);
214
215 std::set<std::string>::const_iterator j;
216 for (j = keys.begin(); j != keys.end(); ++j)
217 observer->OnPrefValueChanged(*j);
218 }
219
RemoveObserver(ExtensionPrefValueMap::Observer * observer)220 void ExtensionPrefValueMap::RemoveObserver(
221 ExtensionPrefValueMap::Observer* observer) {
222 observers_.RemoveObserver(observer);
223 }
224
NotifyInitializationCompleted()225 void ExtensionPrefValueMap::NotifyInitializationCompleted() {
226 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
227 OnInitializationCompleted());
228 }
229
NotifyPrefValueChanged(const std::set<std::string> & keys)230 void ExtensionPrefValueMap::NotifyPrefValueChanged(
231 const std::set<std::string>& keys) {
232 std::set<std::string>::const_iterator i;
233 for (i = keys.begin(); i != keys.end(); ++i)
234 NotifyPrefValueChanged(*i);
235 }
236
NotifyPrefValueChanged(const std::string & key)237 void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
238 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
239 OnPrefValueChanged(key));
240 }
241
NotifyOfDestruction()242 void ExtensionPrefValueMap::NotifyOfDestruction() {
243 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
244 OnExtensionPrefValueMapDestruction());
245 }
246