1 // Copyright (c) 2012 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 "chrome/browser/extensions/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.
18 // Extension controlled preferences for the regular profile.
19 PrefValueMap regular_profile_preferences
;
20 // Extension controlled preferences that should *only* apply to the regular
22 PrefValueMap regular_only_profile_preferences
;
23 // Persistent extension controlled preferences for the incognito profile,
24 // empty for regular profile ExtensionPrefStore.
25 PrefValueMap incognito_profile_preferences_persistent
;
26 // Session only extension controlled preferences for the incognito profile.
27 // These preferences are deleted when the incognito profile is destroyed.
28 PrefValueMap incognito_profile_preferences_session_only
;
31 ExtensionPrefValueMap::ExtensionPrefValueMap() : destroyed_(false) {
34 ExtensionPrefValueMap::~ExtensionPrefValueMap() {
36 NotifyOfDestruction();
39 STLDeleteValues(&entries_
);
43 void ExtensionPrefValueMap::Shutdown() {
44 NotifyOfDestruction();
48 void ExtensionPrefValueMap::SetExtensionPref(const std::string
& ext_id
,
49 const std::string
& key
,
50 ExtensionPrefsScope scope
,
52 PrefValueMap
* prefs
= GetExtensionPrefValueMap(ext_id
, scope
);
54 if (prefs
->SetValue(key
, value
))
55 NotifyPrefValueChanged(key
);
58 void ExtensionPrefValueMap::RemoveExtensionPref(
59 const std::string
& ext_id
,
60 const std::string
& key
,
61 ExtensionPrefsScope scope
) {
62 PrefValueMap
* prefs
= GetExtensionPrefValueMap(ext_id
, scope
);
63 if (prefs
->RemoveValue(key
))
64 NotifyPrefValueChanged(key
);
67 bool ExtensionPrefValueMap::CanExtensionControlPref(
68 const std::string
& extension_id
,
69 const std::string
& pref_key
,
70 bool incognito
) const {
71 ExtensionEntryMap::const_iterator ext
= entries_
.find(extension_id
);
72 if (ext
== entries_
.end()) {
77 ExtensionEntryMap::const_iterator winner
=
78 GetEffectivePrefValueController(pref_key
, incognito
, NULL
);
79 if (winner
== entries_
.end())
82 return winner
->second
->install_time
<= ext
->second
->install_time
;
85 void ExtensionPrefValueMap::ClearAllIncognitoSessionOnlyPreferences() {
86 typedef std::set
<std::string
> KeySet
;
89 ExtensionEntryMap::iterator i
;
90 for (i
= entries_
.begin(); i
!= entries_
.end(); ++i
) {
91 PrefValueMap
& inc_prefs
=
92 i
->second
->incognito_profile_preferences_session_only
;
93 PrefValueMap::iterator j
;
94 for (j
= inc_prefs
.begin(); j
!= inc_prefs
.end(); ++j
)
95 deleted_keys
.insert(j
->first
);
100 for (k
= deleted_keys
.begin(); k
!= deleted_keys
.end(); ++k
)
101 NotifyPrefValueChanged(*k
);
104 bool ExtensionPrefValueMap::DoesExtensionControlPref(
105 const std::string
& extension_id
,
106 const std::string
& pref_key
,
107 bool* from_incognito
) const {
108 bool incognito
= (from_incognito
!= NULL
);
109 ExtensionEntryMap::const_iterator winner
=
110 GetEffectivePrefValueController(pref_key
, incognito
, from_incognito
);
111 if (winner
== entries_
.end())
113 return winner
->first
== extension_id
;
116 void ExtensionPrefValueMap::RegisterExtension(const std::string
& ext_id
,
117 const base::Time
& install_time
,
119 if (entries_
.find(ext_id
) == entries_
.end()) {
120 entries_
[ext_id
] = new ExtensionEntry
;
122 // Only update the install time if the extension is newly installed.
123 entries_
[ext_id
]->install_time
= install_time
;
126 entries_
[ext_id
]->enabled
= is_enabled
;
129 void ExtensionPrefValueMap::UnregisterExtension(const std::string
& ext_id
) {
130 ExtensionEntryMap::iterator i
= entries_
.find(ext_id
);
131 if (i
== entries_
.end())
133 std::set
<std::string
> keys
; // keys set by this extension
134 GetExtensionControlledKeys(*(i
->second
), &keys
);
139 NotifyPrefValueChanged(keys
);
142 void ExtensionPrefValueMap::SetExtensionState(const std::string
& ext_id
,
144 ExtensionEntryMap::const_iterator i
= entries_
.find(ext_id
);
145 // This may happen when sync sets the extension state for an
146 // extension that is not installed.
147 if (i
== entries_
.end())
149 if (i
->second
->enabled
== is_enabled
)
151 std::set
<std::string
> keys
; // keys set by this extension
152 GetExtensionControlledKeys(*(i
->second
), &keys
);
153 i
->second
->enabled
= is_enabled
;
154 NotifyPrefValueChanged(keys
);
157 PrefValueMap
* ExtensionPrefValueMap::GetExtensionPrefValueMap(
158 const std::string
& ext_id
,
159 ExtensionPrefsScope scope
) {
160 ExtensionEntryMap::const_iterator i
= entries_
.find(ext_id
);
161 CHECK(i
!= entries_
.end());
163 case extensions::kExtensionPrefsScopeRegular
:
164 return &(i
->second
->regular_profile_preferences
);
165 case extensions::kExtensionPrefsScopeRegularOnly
:
166 return &(i
->second
->regular_only_profile_preferences
);
167 case extensions::kExtensionPrefsScopeIncognitoPersistent
:
168 return &(i
->second
->incognito_profile_preferences_persistent
);
169 case extensions::kExtensionPrefsScopeIncognitoSessionOnly
:
170 return &(i
->second
->incognito_profile_preferences_session_only
);
176 const PrefValueMap
* ExtensionPrefValueMap::GetExtensionPrefValueMap(
177 const std::string
& ext_id
,
178 ExtensionPrefsScope scope
) const {
179 ExtensionEntryMap::const_iterator i
= entries_
.find(ext_id
);
180 CHECK(i
!= entries_
.end());
182 case extensions::kExtensionPrefsScopeRegular
:
183 return &(i
->second
->regular_profile_preferences
);
184 case extensions::kExtensionPrefsScopeRegularOnly
:
185 return &(i
->second
->regular_only_profile_preferences
);
186 case extensions::kExtensionPrefsScopeIncognitoPersistent
:
187 return &(i
->second
->incognito_profile_preferences_persistent
);
188 case extensions::kExtensionPrefsScopeIncognitoSessionOnly
:
189 return &(i
->second
->incognito_profile_preferences_session_only
);
195 void ExtensionPrefValueMap::GetExtensionControlledKeys(
196 const ExtensionEntry
& entry
,
197 std::set
<std::string
>* out
) const {
198 PrefValueMap::const_iterator i
;
200 const PrefValueMap
& regular_prefs
= entry
.regular_profile_preferences
;
201 for (i
= regular_prefs
.begin(); i
!= regular_prefs
.end(); ++i
)
202 out
->insert(i
->first
);
204 const PrefValueMap
& regular_only_prefs
=
205 entry
.regular_only_profile_preferences
;
206 for (i
= regular_only_prefs
.begin(); i
!= regular_only_prefs
.end(); ++i
)
207 out
->insert(i
->first
);
209 const PrefValueMap
& inc_prefs_pers
=
210 entry
.incognito_profile_preferences_persistent
;
211 for (i
= inc_prefs_pers
.begin(); i
!= inc_prefs_pers
.end(); ++i
)
212 out
->insert(i
->first
);
214 const PrefValueMap
& inc_prefs_session
=
215 entry
.incognito_profile_preferences_session_only
;
216 for (i
= inc_prefs_session
.begin(); i
!= inc_prefs_session
.end(); ++i
)
217 out
->insert(i
->first
);
220 const base::Value
* ExtensionPrefValueMap::GetEffectivePrefValue(
221 const std::string
& key
,
223 bool* from_incognito
) const {
224 ExtensionEntryMap::const_iterator winner
=
225 GetEffectivePrefValueController(key
, incognito
, from_incognito
);
226 if (winner
== entries_
.end())
229 const base::Value
* value
= NULL
;
230 const std::string
& ext_id
= winner
->first
;
232 // First search for incognito session only preferences.
234 const PrefValueMap
* prefs
= GetExtensionPrefValueMap(
235 ext_id
, extensions::kExtensionPrefsScopeIncognitoSessionOnly
);
236 prefs
->GetValue(key
, &value
);
240 // If no incognito session only preference exists, fall back to persistent
241 // incognito preference.
242 prefs
= GetExtensionPrefValueMap(
244 extensions::kExtensionPrefsScopeIncognitoPersistent
);
245 prefs
->GetValue(key
, &value
);
249 // Regular-only preference.
250 const PrefValueMap
* prefs
= GetExtensionPrefValueMap(
251 ext_id
, extensions::kExtensionPrefsScopeRegularOnly
);
252 prefs
->GetValue(key
, &value
);
257 // Regular preference.
258 const PrefValueMap
* prefs
= GetExtensionPrefValueMap(
259 ext_id
, extensions::kExtensionPrefsScopeRegular
);
260 prefs
->GetValue(key
, &value
);
264 ExtensionPrefValueMap::ExtensionEntryMap::const_iterator
265 ExtensionPrefValueMap::GetEffectivePrefValueController(
266 const std::string
& key
,
268 bool* from_incognito
) const {
269 ExtensionEntryMap::const_iterator winner
= entries_
.end();
270 base::Time winners_install_time
;
272 ExtensionEntryMap::const_iterator i
;
273 for (i
= entries_
.begin(); i
!= entries_
.end(); ++i
) {
274 const std::string
& ext_id
= i
->first
;
275 const base::Time
& install_time
= i
->second
->install_time
;
276 const bool enabled
= i
->second
->enabled
;
280 if (install_time
< winners_install_time
)
283 const base::Value
* value
= NULL
;
284 const PrefValueMap
* prefs
= GetExtensionPrefValueMap(
285 ext_id
, extensions::kExtensionPrefsScopeRegular
);
286 if (prefs
->GetValue(key
, &value
)) {
288 winners_install_time
= install_time
;
290 *from_incognito
= false;
294 const PrefValueMap
* prefs
= GetExtensionPrefValueMap(
295 ext_id
, extensions::kExtensionPrefsScopeRegularOnly
);
296 if (prefs
->GetValue(key
, &value
)) {
298 winners_install_time
= install_time
;
300 *from_incognito
= false;
302 // Ignore the following prefs, because they're incognito-only.
306 prefs
= GetExtensionPrefValueMap(
307 ext_id
, extensions::kExtensionPrefsScopeIncognitoPersistent
);
308 if (prefs
->GetValue(key
, &value
)) {
310 winners_install_time
= install_time
;
312 *from_incognito
= true;
315 prefs
= GetExtensionPrefValueMap(
316 ext_id
, extensions::kExtensionPrefsScopeIncognitoSessionOnly
);
317 if (prefs
->GetValue(key
, &value
)) {
319 winners_install_time
= install_time
;
321 *from_incognito
= true;
327 void ExtensionPrefValueMap::AddObserver(
328 ExtensionPrefValueMap::Observer
* observer
) {
329 observers_
.AddObserver(observer
);
331 // Collect all currently used keys and notify the new observer.
332 std::set
<std::string
> keys
;
333 ExtensionEntryMap::const_iterator i
;
334 for (i
= entries_
.begin(); i
!= entries_
.end(); ++i
)
335 GetExtensionControlledKeys(*(i
->second
), &keys
);
337 std::set
<std::string
>::const_iterator j
;
338 for (j
= keys
.begin(); j
!= keys
.end(); ++j
)
339 observer
->OnPrefValueChanged(*j
);
342 void ExtensionPrefValueMap::RemoveObserver(
343 ExtensionPrefValueMap::Observer
* observer
) {
344 observers_
.RemoveObserver(observer
);
347 std::string
ExtensionPrefValueMap::GetExtensionControllingPref(
348 const std::string
& pref_key
) const {
349 ExtensionEntryMap::const_iterator winner
=
350 GetEffectivePrefValueController(pref_key
, false, NULL
);
351 if (winner
== entries_
.end())
352 return std::string();
353 return winner
->first
;
356 void ExtensionPrefValueMap::NotifyInitializationCompleted() {
357 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer
, observers_
,
358 OnInitializationCompleted());
361 void ExtensionPrefValueMap::NotifyPrefValueChanged(
362 const std::set
<std::string
>& keys
) {
363 std::set
<std::string
>::const_iterator i
;
364 for (i
= keys
.begin(); i
!= keys
.end(); ++i
)
365 NotifyPrefValueChanged(*i
);
368 void ExtensionPrefValueMap::NotifyPrefValueChanged(const std::string
& key
) {
369 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer
, observers_
,
370 OnPrefValueChanged(key
));
373 void ExtensionPrefValueMap::NotifyOfDestruction() {
374 FOR_EACH_OBSERVER(ExtensionPrefValueMap::Observer
, observers_
,
375 OnExtensionPrefValueMapDestruction());