blob: fb4abdfe86510b67d5c9a1225903f4d81902077b [file] [log] [blame]
[email protected]9a8c4022011-01-25 14:25:331// 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
[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;
16 // Regular preferences.
17 PrefValueMap reg_preferences;
18 // Incognito preferences, empty for regular ExtensionPrefStore.
19 PrefValueMap inc_preferences;
20};
21
[email protected]9a8c4022011-01-25 14:25:3322ExtensionPrefValueMap::ExtensionPrefValueMap() {
23}
24
25ExtensionPrefValueMap::~ExtensionPrefValueMap() {
26 NotifyOfDestruction();
27 STLDeleteValues(&entries_);
28 entries_.clear();
29}
30
31void 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
41void 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
[email protected]9a28f132011-02-24 21:15:1649bool 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);
61 if (winner == entries_.end())
62 return true;
63
64 return winner->second->install_time <= ext->second->install_time;
65}
66
67bool 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);
73 if (winner == entries_.end())
74 return false;
75 return winner->first == extension_id;
76}
77
[email protected]9a8c4022011-01-25 14:25:3378void 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
88void 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
101void 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
113PrefValueMap* 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
122const 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
131void 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
145const Value* ExtensionPrefValueMap::GetEffectivePrefValue(
146 const std::string& key,
147 bool incognito) const {
[email protected]9a28f132011-02-24 21:15:16148 ExtensionEntryMap::const_iterator winner =
149 GetEffectivePrefValueController(key, incognito);
150 if (winner == entries_.end())
151 return NULL;
152
153 Value* value = NULL;
154 const std::string& ext_id = winner->first;
155 if (incognito)
156 GetExtensionPrefValueMap(ext_id, true)->GetValue(key, &value);
157 if (!value)
158 GetExtensionPrefValueMap(ext_id, false)->GetValue(key, &value);
159 return value;
160}
161
162ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
163ExtensionPrefValueMap::GetEffectivePrefValueController(
164 const std::string& key,
165 bool incognito) const {
166 ExtensionEntryMap::const_iterator winner = entries_.end();
[email protected]9a8c4022011-01-25 14:25:33167 base::Time winners_install_time;
168
169 ExtensionEntryMap::const_iterator i;
170 for (i = entries_.begin(); i != entries_.end(); ++i) {
171 const std::string& ext_id = i->first;
172 const base::Time& install_time = i->second->install_time;
173 const bool enabled = i->second->enabled;
174
175 if (!enabled)
176 continue;
177 if (install_time < winners_install_time)
178 continue;
179
180 Value* value = NULL;
181 const PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, false);
182 if (prefs->GetValue(key, &value)) {
[email protected]9a28f132011-02-24 21:15:16183 winner = i;
[email protected]9a8c4022011-01-25 14:25:33184 winners_install_time = install_time;
185 }
186
187 if (!incognito)
188 continue;
189
190 prefs = GetExtensionPrefValueMap(ext_id, true);
191 if (prefs->GetValue(key, &value)) {
[email protected]9a28f132011-02-24 21:15:16192 winner = i;
[email protected]9a8c4022011-01-25 14:25:33193 winners_install_time = install_time;
194 }
195 }
196 return winner;
197}
198
199void ExtensionPrefValueMap::AddObserver(
200 ExtensionPrefValueMap::Observer* observer) {
201 observers_.AddObserver(observer);
202
203 // Collect all currently used keys and notify the new observer.
204 std::set<std::string> keys;
205 ExtensionEntryMap::const_iterator i;
206 for (i = entries_.begin(); i != entries_.end(); ++i)
207 GetExtensionControlledKeys(*(i->second), &keys);
208
209 std::set<std::string>::const_iterator j;
210 for (j = keys.begin(); j != keys.end(); ++j)
211 observer->OnPrefValueChanged(*j);
212}
213
214void ExtensionPrefValueMap::RemoveObserver(
215 ExtensionPrefValueMap::Observer* observer) {
216 observers_.RemoveObserver(observer);
217}
218
219void ExtensionPrefValueMap::NotifyInitializationCompleted() {
220 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
221 OnInitializationCompleted());
222}
223
224void ExtensionPrefValueMap::NotifyPrefValueChanged(
225 const std::set<std::string>& keys) {
226 std::set<std::string>::const_iterator i;
227 for (i = keys.begin(); i != keys.end(); ++i)
228 NotifyPrefValueChanged(*i);
229}
230
231void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
232 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
233 OnPrefValueChanged(key));
234}
235
236void ExtensionPrefValueMap::NotifyOfDestruction() {
237 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
238 OnExtensionPrefValueMapDestruction());
239}