Chromecast on Android buildfix: don't try to create a RendererFactory.
[chromium-blink-merge.git] / extensions / browser / extension_pref_value_map.cc
blob0797b2416e3c03e7eaf55985e88a0fae77f2bbc3
1 // Copyright 2014 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 "extensions/browser/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 // Whether the extension has access to the incognito profile.
19 bool incognito_enabled;
20 // Extension controlled preferences for the regular profile.
21 PrefValueMap regular_profile_preferences;
22 // Extension controlled preferences that should *only* apply to the regular
23 // profile.
24 PrefValueMap regular_only_profile_preferences;
25 // Persistent extension controlled preferences for the incognito profile,
26 // empty for regular profile ExtensionPrefStore.
27 PrefValueMap incognito_profile_preferences_persistent;
28 // Session only extension controlled preferences for the incognito profile.
29 // These preferences are deleted when the incognito profile is destroyed.
30 PrefValueMap incognito_profile_preferences_session_only;
33 ExtensionPrefValueMap::ExtensionPrefValueMap() : destroyed_(false) {
36 ExtensionPrefValueMap::~ExtensionPrefValueMap() {
37 if (!destroyed_) {
38 NotifyOfDestruction();
39 destroyed_ = true;
41 STLDeleteValues(&entries_);
42 entries_.clear();
45 void ExtensionPrefValueMap::Shutdown() {
46 NotifyOfDestruction();
47 destroyed_ = true;
50 void ExtensionPrefValueMap::SetExtensionPref(const std::string& ext_id,
51 const std::string& key,
52 ExtensionPrefsScope scope,
53 base::Value* value) {
54 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
56 if (prefs->SetValue(key, value))
57 NotifyPrefValueChanged(key);
60 void ExtensionPrefValueMap::RemoveExtensionPref(
61 const std::string& ext_id,
62 const std::string& key,
63 ExtensionPrefsScope scope) {
64 PrefValueMap* prefs = GetExtensionPrefValueMap(ext_id, scope);
65 if (prefs->RemoveValue(key))
66 NotifyPrefValueChanged(key);
69 bool ExtensionPrefValueMap::CanExtensionControlPref(
70 const std::string& extension_id,
71 const std::string& pref_key,
72 bool incognito) const {
73 ExtensionEntryMap::const_iterator ext = entries_.find(extension_id);
74 if (ext == entries_.end()) {
75 NOTREACHED();
76 return false;
79 if (incognito && !ext->second->incognito_enabled)
80 return false;
82 ExtensionEntryMap::const_iterator winner =
83 GetEffectivePrefValueController(pref_key, incognito, NULL);
84 if (winner == entries_.end())
85 return true;
87 return winner->second->install_time <= ext->second->install_time;
90 void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() {
91 typedef std::set<std::string> KeySet;
92 KeySet deleted_keys;
94 ExtensionEntryMap::iterator i;
95 for (i = entries_.begin(); i != entries_.end(); ++i) {
96 PrefValueMap& inc_prefs =
97 i->second->incognito_profile_preferences_session_only;
98 PrefValueMap::iterator j;
99 for (j = inc_prefs.begin(); j != inc_prefs.end(); ++j)
100 deleted_keys.insert(j->first);
101 inc_prefs.Clear();
104 KeySet::iterator k;
105 for (k = deleted_keys.begin(); k != deleted_keys.end(); ++k)
106 NotifyPrefValueChanged(*k);
109 bool ExtensionPrefValueMap::DoesExtensionControlPref(
110 const std::string& extension_id,
111 const std::string& pref_key,
112 bool* from_incognito) const {
113 bool incognito = (from_incognito != NULL);
114 ExtensionEntryMap::const_iterator winner =
115 GetEffectivePrefValueController(pref_key, incognito, from_incognito);
116 if (winner == entries_.end())
117 return false;
118 return winner->first == extension_id;
121 void ExtensionPrefValueMap::RegisterExtension(const std::string& ext_id,
122 const base::Time& install_time,
123 bool is_enabled,
124 bool is_incognito_enabled) {
125 if (entries_.find(ext_id) == entries_.end()) {
126 entries_[ext_id] = new ExtensionEntry;
128 // Only update the install time if the extension is newly installed.
129 entries_[ext_id]->install_time = install_time;
132 entries_[ext_id]->enabled = is_enabled;
133 entries_[ext_id]->incognito_enabled = is_incognito_enabled;
136 void ExtensionPrefValueMap::UnregisterExtension(const std::string& ext_id) {
137 ExtensionEntryMap::iterator i = entries_.find(ext_id);
138 if (i == entries_.end())
139 return;
140 std::set<std::string> keys; // keys set by this extension
141 GetExtensionControlledKeys(*(i->second), &keys);
143 delete i->second;
144 entries_.erase(i);
146 NotifyPrefValueChanged(keys);
149 void ExtensionPrefValueMap::SetExtensionState(const std::string& ext_id,
150 bool is_enabled) {
151 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
152 // This may happen when sync sets the extension state for an
153 // extension that is not installed.
154 if (i == entries_.end())
155 return;
156 if (i->second->enabled == is_enabled)
157 return;
158 std::set<std::string> keys; // keys set by this extension
159 GetExtensionControlledKeys(*(i->second), &keys);
160 i->second->enabled = is_enabled;
161 NotifyPrefValueChanged(keys);
164 void ExtensionPrefValueMap::SetExtensionIncognitoState(
165 const std::string& ext_id,
166 bool is_incognito_enabled) {
167 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
168 // This may happen when sync sets the extension state for an
169 // extension that is not installed.
170 if (i == entries_.end())
171 return;
172 if (i->second->incognito_enabled == is_incognito_enabled)
173 return;
174 std::set<std::string> keys; // keys set by this extension
175 GetExtensionControlledKeys(*(i->second), &keys);
176 i->second->incognito_enabled = is_incognito_enabled;
177 NotifyPrefValueChanged(keys);
180 PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
181 const std::string& ext_id,
182 ExtensionPrefsScope scope) {
183 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
184 CHECK(i != entries_.end());
185 switch (scope) {
186 case extensions::kExtensionPrefsScopeRegular:
187 return &(i->second->regular_profile_preferences);
188 case extensions::kExtensionPrefsScopeRegularOnly:
189 return &(i->second->regular_only_profile_preferences);
190 case extensions::kExtensionPrefsScopeIncognitoPersistent:
191 return &(i->second->incognito_profile_preferences_persistent);
192 case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
193 return &(i->second->incognito_profile_preferences_session_only);
195 NOTREACHED();
196 return NULL;
199 const PrefValueMap* ExtensionPrefValueMap::GetExtensionPrefValueMap(
200 const std::string& ext_id,
201 ExtensionPrefsScope scope) const {
202 ExtensionEntryMap::const_iterator i = entries_.find(ext_id);
203 CHECK(i != entries_.end());
204 switch (scope) {
205 case extensions::kExtensionPrefsScopeRegular:
206 return &(i->second->regular_profile_preferences);
207 case extensions::kExtensionPrefsScopeRegularOnly:
208 return &(i->second->regular_only_profile_preferences);
209 case extensions::kExtensionPrefsScopeIncognitoPersistent:
210 return &(i->second->incognito_profile_preferences_persistent);
211 case extensions::kExtensionPrefsScopeIncognitoSessionOnly:
212 return &(i->second->incognito_profile_preferences_session_only);
214 NOTREACHED();
215 return NULL;
218 void ExtensionPrefValueMap::GetExtensionControlledKeys(
219 const ExtensionEntry& entry,
220 std::set<std::string>* out) const {
221 PrefValueMap::const_iterator i;
223 const PrefValueMap& regular_prefs = entry.regular_profile_preferences;
224 for (i = regular_prefs.begin(); i != regular_prefs.end(); ++i)
225 out->insert(i->first);
227 const PrefValueMap& regular_only_prefs =
228 entry.regular_only_profile_preferences;
229 for (i = regular_only_prefs.begin(); i != regular_only_prefs.end(); ++i)
230 out->insert(i->first);
232 const PrefValueMap& inc_prefs_pers =
233 entry.incognito_profile_preferences_persistent;
234 for (i = inc_prefs_pers.begin(); i != inc_prefs_pers.end(); ++i)
235 out->insert(i->first);
237 const PrefValueMap& inc_prefs_session =
238 entry.incognito_profile_preferences_session_only;
239 for (i = inc_prefs_session.begin(); i != inc_prefs_session.end(); ++i)
240 out->insert(i->first);
243 const base::Value* ExtensionPrefValueMap::GetEffectivePrefValue(
244 const std::string& key,
245 bool incognito,
246 bool* from_incognito) const {
247 ExtensionEntryMap::const_iterator winner =
248 GetEffectivePrefValueController(key, incognito, from_incognito);
249 if (winner == entries_.end())
250 return NULL;
252 const base::Value* value = NULL;
253 const std::string& ext_id = winner->first;
255 // First search for incognito session only preferences.
256 if (incognito) {
257 DCHECK(winner->second->incognito_enabled);
258 const PrefValueMap* prefs = GetExtensionPrefValueMap(
259 ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
260 prefs->GetValue(key, &value);
261 if (value)
262 return value;
264 // If no incognito session only preference exists, fall back to persistent
265 // incognito preference.
266 prefs = GetExtensionPrefValueMap(
267 ext_id,
268 extensions::kExtensionPrefsScopeIncognitoPersistent);
269 prefs->GetValue(key, &value);
270 if (value)
271 return value;
272 } else {
273 // Regular-only preference.
274 const PrefValueMap* prefs = GetExtensionPrefValueMap(
275 ext_id, extensions::kExtensionPrefsScopeRegularOnly);
276 prefs->GetValue(key, &value);
277 if (value)
278 return value;
281 // Regular preference.
282 const PrefValueMap* prefs = GetExtensionPrefValueMap(
283 ext_id, extensions::kExtensionPrefsScopeRegular);
284 prefs->GetValue(key, &value);
285 return value;
288 ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
289 ExtensionPrefValueMap::GetEffectivePrefValueController(
290 const std::string& key,
291 bool incognito,
292 bool* from_incognito) const {
293 ExtensionEntryMap::const_iterator winner = entries_.end();
294 base::Time winners_install_time;
296 ExtensionEntryMap::const_iterator i;
297 for (i = entries_.begin(); i != entries_.end(); ++i) {
298 const std::string& ext_id = i->first;
299 const base::Time& install_time = i->second->install_time;
300 const bool enabled = i->second->enabled;
301 const bool incognito_enabled = i->second->incognito_enabled;
303 if (!enabled)
304 continue;
305 if (install_time < winners_install_time)
306 continue;
307 if (incognito && !incognito_enabled)
308 continue;
310 const base::Value* value = NULL;
311 const PrefValueMap* prefs = GetExtensionPrefValueMap(
312 ext_id, extensions::kExtensionPrefsScopeRegular);
313 if (prefs->GetValue(key, &value)) {
314 winner = i;
315 winners_install_time = install_time;
316 if (from_incognito)
317 *from_incognito = false;
320 if (!incognito) {
321 const PrefValueMap* prefs = GetExtensionPrefValueMap(
322 ext_id, extensions::kExtensionPrefsScopeRegularOnly);
323 if (prefs->GetValue(key, &value)) {
324 winner = i;
325 winners_install_time = install_time;
326 if (from_incognito)
327 *from_incognito = false;
329 // Ignore the following prefs, because they're incognito-only.
330 continue;
333 prefs = GetExtensionPrefValueMap(
334 ext_id, extensions::kExtensionPrefsScopeIncognitoPersistent);
335 if (prefs->GetValue(key, &value)) {
336 winner = i;
337 winners_install_time = install_time;
338 if (from_incognito)
339 *from_incognito = true;
342 prefs = GetExtensionPrefValueMap(
343 ext_id, extensions::kExtensionPrefsScopeIncognitoSessionOnly);
344 if (prefs->GetValue(key, &value)) {
345 winner = i;
346 winners_install_time = install_time;
347 if (from_incognito)
348 *from_incognito = true;
351 return winner;
354 void ExtensionPrefValueMap::AddObserver(
355 ExtensionPrefValueMap::Observer* observer) {
356 observers_.AddObserver(observer);
358 // Collect all currently used keys and notify the new observer.
359 std::set<std::string> keys;
360 ExtensionEntryMap::const_iterator i;
361 for (i = entries_.begin(); i != entries_.end(); ++i)
362 GetExtensionControlledKeys(*(i->second), &keys);
364 std::set<std::string>::const_iterator j;
365 for (j = keys.begin(); j != keys.end(); ++j)
366 observer->OnPrefValueChanged(*j);
369 void ExtensionPrefValueMap::RemoveObserver(
370 ExtensionPrefValueMap::Observer* observer) {
371 observers_.RemoveObserver(observer);
374 std::string ExtensionPrefValueMap::GetExtensionControllingPref(
375 const std::string& pref_key) const {
376 ExtensionEntryMap::const_iterator winner =
377 GetEffectivePrefValueController(pref_key, false, NULL);
378 if (winner == entries_.end())
379 return std::string();
380 return winner->first;
383 void ExtensionPrefValueMap::NotifyInitializationCompleted() {
384 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
385 OnInitializationCompleted());
388 void ExtensionPrefValueMap::NotifyPrefValueChanged(
389 const std::set<std::string>& keys) {
390 std::set<std::string>::const_iterator i;
391 for (i = keys.begin(); i != keys.end(); ++i)
392 NotifyPrefValueChanged(*i);
395 void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string& key) {
396 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
397 OnPrefValueChanged(key));
400 void ExtensionPrefValueMap::NotifyOfDestruction() {
401 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer, observers_,
402 OnExtensionPrefValueMapDestruction());