• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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