OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_content_settings_store.h" | 5 #include "chrome/browser/extensions/api/content_settings/content_settings_store.
h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/memory/scoped_vector.h" | 11 #include "base/memory/scoped_vector.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/extensions/api/content_settings/content_settings_api_co
nstants.h" |
| 15 #include "chrome/browser/extensions/api/content_settings/content_settings_helper
s.h" |
14 #include "chrome/browser/content_settings/content_settings_origin_identifier_val
ue_map.h" | 16 #include "chrome/browser/content_settings/content_settings_origin_identifier_val
ue_map.h" |
15 #include "chrome/browser/content_settings/content_settings_rule.h" | 17 #include "chrome/browser/content_settings/content_settings_rule.h" |
16 #include "chrome/browser/content_settings/content_settings_utils.h" | 18 #include "chrome/browser/content_settings/content_settings_utils.h" |
17 #include "chrome/browser/extensions/extension_content_settings_api_constants.h" | |
18 #include "chrome/browser/extensions/extension_content_settings_helpers.h" | |
19 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
20 | 20 |
21 namespace helpers = extension_content_settings_helpers; | |
22 namespace keys = extension_content_settings_api_constants; | |
23 | |
24 using content::BrowserThread; | 21 using content::BrowserThread; |
25 using content_settings::ConcatenationIterator; | 22 using content_settings::ConcatenationIterator; |
26 using content_settings::Rule; | 23 using content_settings::Rule; |
27 using content_settings::RuleIterator; | 24 using content_settings::RuleIterator; |
28 using content_settings::OriginIdentifierValueMap; | 25 using content_settings::OriginIdentifierValueMap; |
29 using content_settings::ResourceIdentifier; | 26 using content_settings::ResourceIdentifier; |
30 using content_settings::ValueToContentSetting; | 27 using content_settings::ValueToContentSetting; |
31 | 28 |
32 struct ExtensionContentSettingsStore::ExtensionEntry { | 29 namespace extensions { |
| 30 |
| 31 namespace helpers = content_settings_helpers; |
| 32 namespace keys = content_settings_api_constants; |
| 33 |
| 34 struct ContentSettingsStore::ExtensionEntry { |
33 // Extension id | 35 // Extension id |
34 std::string id; | 36 std::string id; |
35 // Whether extension is enabled in the profile. | 37 // Whether extension is enabled in the profile. |
36 bool enabled; | 38 bool enabled; |
37 // Content settings. | 39 // Content settings. |
38 OriginIdentifierValueMap settings; | 40 OriginIdentifierValueMap settings; |
39 // Persistent incognito content settings. | 41 // Persistent incognito content settings. |
40 OriginIdentifierValueMap incognito_persistent_settings; | 42 OriginIdentifierValueMap incognito_persistent_settings; |
41 // Session-only incognito content settings. | 43 // Session-only incognito content settings. |
42 OriginIdentifierValueMap incognito_session_only_settings; | 44 OriginIdentifierValueMap incognito_session_only_settings; |
43 }; | 45 }; |
44 | 46 |
45 ExtensionContentSettingsStore::ExtensionContentSettingsStore() { | 47 ContentSettingsStore::ContentSettingsStore() { |
46 DCHECK(OnCorrectThread()); | 48 DCHECK(OnCorrectThread()); |
47 } | 49 } |
48 | 50 |
49 ExtensionContentSettingsStore::~ExtensionContentSettingsStore() { | 51 ContentSettingsStore::~ContentSettingsStore() { |
50 STLDeleteValues(&entries_); | 52 STLDeleteValues(&entries_); |
51 } | 53 } |
52 | 54 |
53 RuleIterator* ExtensionContentSettingsStore::GetRuleIterator( | 55 RuleIterator* ContentSettingsStore::GetRuleIterator( |
54 ContentSettingsType type, | 56 ContentSettingsType type, |
55 const content_settings::ResourceIdentifier& identifier, | 57 const content_settings::ResourceIdentifier& identifier, |
56 bool incognito) const { | 58 bool incognito) const { |
57 ScopedVector<RuleIterator> iterators; | 59 ScopedVector<RuleIterator> iterators; |
58 // Iterate the extensions based on install time (last installed extensions | 60 // Iterate the extensions based on install time (last installed extensions |
59 // first). | 61 // first). |
60 ExtensionEntryMap::const_reverse_iterator entry; | 62 ExtensionEntryMap::const_reverse_iterator entry; |
61 | 63 |
62 // The individual |RuleIterators| shouldn't lock; pass |lock_| to the | 64 // The individual |RuleIterators| shouldn't lock; pass |lock_| to the |
63 // |ConcatenationIterator| in a locked state. | 65 // |ConcatenationIterator| in a locked state. |
(...skipping 15 matching lines...) Expand all Loading... |
79 identifier, | 81 identifier, |
80 NULL)); | 82 NULL)); |
81 } else { | 83 } else { |
82 iterators.push_back( | 84 iterators.push_back( |
83 entry->second->settings.GetRuleIterator(type, identifier, NULL)); | 85 entry->second->settings.GetRuleIterator(type, identifier, NULL)); |
84 } | 86 } |
85 } | 87 } |
86 return new ConcatenationIterator(&iterators, auto_lock.release()); | 88 return new ConcatenationIterator(&iterators, auto_lock.release()); |
87 } | 89 } |
88 | 90 |
89 void ExtensionContentSettingsStore::SetExtensionContentSetting( | 91 void ContentSettingsStore::SetExtensionContentSetting( |
90 const std::string& ext_id, | 92 const std::string& ext_id, |
91 const ContentSettingsPattern& primary_pattern, | 93 const ContentSettingsPattern& primary_pattern, |
92 const ContentSettingsPattern& secondary_pattern, | 94 const ContentSettingsPattern& secondary_pattern, |
93 ContentSettingsType type, | 95 ContentSettingsType type, |
94 const content_settings::ResourceIdentifier& identifier, | 96 const content_settings::ResourceIdentifier& identifier, |
95 ContentSetting setting, | 97 ContentSetting setting, |
96 ExtensionPrefsScope scope) { | 98 ExtensionPrefsScope scope) { |
97 { | 99 { |
98 base::AutoLock lock(lock_); | 100 base::AutoLock lock(lock_); |
99 OriginIdentifierValueMap* map = GetValueMap(ext_id, scope); | 101 OriginIdentifierValueMap* map = GetValueMap(ext_id, scope); |
100 if (setting == CONTENT_SETTING_DEFAULT) { | 102 if (setting == CONTENT_SETTING_DEFAULT) { |
101 map->DeleteValue(primary_pattern, secondary_pattern, type, identifier); | 103 map->DeleteValue(primary_pattern, secondary_pattern, type, identifier); |
102 } else { | 104 } else { |
103 map->SetValue(primary_pattern, secondary_pattern, type, identifier, | 105 map->SetValue(primary_pattern, secondary_pattern, type, identifier, |
104 base::Value::CreateIntegerValue(setting)); | 106 base::Value::CreateIntegerValue(setting)); |
105 } | 107 } |
106 } | 108 } |
107 | 109 |
108 // Send notification that content settings changed. | 110 // Send notification that content settings changed. |
109 // TODO(markusheintz): Notifications should only be sent if the set content | 111 // TODO(markusheintz): Notifications should only be sent if the set content |
110 // setting is effective and not hidden by another setting of another | 112 // setting is effective and not hidden by another setting of another |
111 // extension installed more recently. | 113 // extension installed more recently. |
112 NotifyOfContentSettingChanged(ext_id, | 114 NotifyOfContentSettingChanged(ext_id, |
113 scope != kExtensionPrefsScopeRegular); | 115 scope != kExtensionPrefsScopeRegular); |
114 } | 116 } |
115 | 117 |
116 void ExtensionContentSettingsStore::RegisterExtension( | 118 void ContentSettingsStore::RegisterExtension( |
117 const std::string& ext_id, | 119 const std::string& ext_id, |
118 const base::Time& install_time, | 120 const base::Time& install_time, |
119 bool is_enabled) { | 121 bool is_enabled) { |
120 base::AutoLock lock(lock_); | 122 base::AutoLock lock(lock_); |
121 ExtensionEntryMap::iterator i = FindEntry(ext_id); | 123 ExtensionEntryMap::iterator i = FindEntry(ext_id); |
122 if (i != entries_.end()) { | 124 if (i != entries_.end()) { |
123 delete i->second; | 125 delete i->second; |
124 entries_.erase(i); | 126 entries_.erase(i); |
125 } | 127 } |
126 | 128 |
127 ExtensionEntry* entry = new ExtensionEntry; | 129 ExtensionEntry* entry = new ExtensionEntry; |
128 entry->id = ext_id; | 130 entry->id = ext_id; |
129 entry->enabled = is_enabled; | 131 entry->enabled = is_enabled; |
130 entries_.insert(std::make_pair(install_time, entry)); | 132 entries_.insert(std::make_pair(install_time, entry)); |
131 } | 133 } |
132 | 134 |
133 void ExtensionContentSettingsStore::UnregisterExtension( | 135 void ContentSettingsStore::UnregisterExtension( |
134 const std::string& ext_id) { | 136 const std::string& ext_id) { |
135 bool notify = false; | 137 bool notify = false; |
136 bool notify_incognito = false; | 138 bool notify_incognito = false; |
137 { | 139 { |
138 base::AutoLock lock(lock_); | 140 base::AutoLock lock(lock_); |
139 ExtensionEntryMap::iterator i = FindEntry(ext_id); | 141 ExtensionEntryMap::iterator i = FindEntry(ext_id); |
140 if (i == entries_.end()) | 142 if (i == entries_.end()) |
141 return; | 143 return; |
142 notify = !i->second->settings.empty(); | 144 notify = !i->second->settings.empty(); |
143 notify_incognito = !i->second->incognito_persistent_settings.empty() || | 145 notify_incognito = !i->second->incognito_persistent_settings.empty() || |
144 !i->second->incognito_session_only_settings.empty(); | 146 !i->second->incognito_session_only_settings.empty(); |
145 | 147 |
146 delete i->second; | 148 delete i->second; |
147 entries_.erase(i); | 149 entries_.erase(i); |
148 } | 150 } |
149 if (notify) | 151 if (notify) |
150 NotifyOfContentSettingChanged(ext_id, false); | 152 NotifyOfContentSettingChanged(ext_id, false); |
151 if (notify_incognito) | 153 if (notify_incognito) |
152 NotifyOfContentSettingChanged(ext_id, true); | 154 NotifyOfContentSettingChanged(ext_id, true); |
153 } | 155 } |
154 | 156 |
155 void ExtensionContentSettingsStore::SetExtensionState( | 157 void ContentSettingsStore::SetExtensionState( |
156 const std::string& ext_id, bool is_enabled) { | 158 const std::string& ext_id, bool is_enabled) { |
157 bool notify = false; | 159 bool notify = false; |
158 bool notify_incognito = false; | 160 bool notify_incognito = false; |
159 { | 161 { |
160 base::AutoLock lock(lock_); | 162 base::AutoLock lock(lock_); |
161 ExtensionEntryMap::const_iterator i = FindEntry(ext_id); | 163 ExtensionEntryMap::const_iterator i = FindEntry(ext_id); |
162 if (i == entries_.end()) | 164 if (i == entries_.end()) |
163 return; | 165 return; |
164 notify = !i->second->settings.empty(); | 166 notify = !i->second->settings.empty(); |
165 notify_incognito = !i->second->incognito_persistent_settings.empty() || | 167 notify_incognito = !i->second->incognito_persistent_settings.empty() || |
166 !i->second->incognito_session_only_settings.empty(); | 168 !i->second->incognito_session_only_settings.empty(); |
167 | 169 |
168 i->second->enabled = is_enabled; | 170 i->second->enabled = is_enabled; |
169 } | 171 } |
170 if (notify) | 172 if (notify) |
171 NotifyOfContentSettingChanged(ext_id, false); | 173 NotifyOfContentSettingChanged(ext_id, false); |
172 if (notify_incognito) | 174 if (notify_incognito) |
173 NotifyOfContentSettingChanged(ext_id, true); | 175 NotifyOfContentSettingChanged(ext_id, true); |
174 } | 176 } |
175 | 177 |
176 OriginIdentifierValueMap* ExtensionContentSettingsStore::GetValueMap( | 178 OriginIdentifierValueMap* ContentSettingsStore::GetValueMap( |
177 const std::string& ext_id, | 179 const std::string& ext_id, |
178 ExtensionPrefsScope scope) { | 180 ExtensionPrefsScope scope) { |
179 ExtensionEntryMap::const_iterator i = FindEntry(ext_id); | 181 ExtensionEntryMap::const_iterator i = FindEntry(ext_id); |
180 if (i != entries_.end()) { | 182 if (i != entries_.end()) { |
181 switch (scope) { | 183 switch (scope) { |
182 case kExtensionPrefsScopeRegular: | 184 case kExtensionPrefsScopeRegular: |
183 return &(i->second->settings); | 185 return &(i->second->settings); |
184 case kExtensionPrefsScopeIncognitoPersistent: | 186 case kExtensionPrefsScopeIncognitoPersistent: |
185 return &(i->second->incognito_persistent_settings); | 187 return &(i->second->incognito_persistent_settings); |
186 case kExtensionPrefsScopeIncognitoSessionOnly: | 188 case kExtensionPrefsScopeIncognitoSessionOnly: |
187 return &(i->second->incognito_session_only_settings); | 189 return &(i->second->incognito_session_only_settings); |
188 } | 190 } |
189 } | 191 } |
190 return NULL; | 192 return NULL; |
191 } | 193 } |
192 | 194 |
193 const OriginIdentifierValueMap* ExtensionContentSettingsStore::GetValueMap( | 195 const OriginIdentifierValueMap* ContentSettingsStore::GetValueMap( |
194 const std::string& ext_id, | 196 const std::string& ext_id, |
195 ExtensionPrefsScope scope) const { | 197 ExtensionPrefsScope scope) const { |
196 ExtensionEntryMap::const_iterator i = FindEntry(ext_id); | 198 ExtensionEntryMap::const_iterator i = FindEntry(ext_id); |
197 if (i != entries_.end()) { | 199 if (i != entries_.end()) { |
198 switch (scope) { | 200 switch (scope) { |
199 case kExtensionPrefsScopeRegular: | 201 case kExtensionPrefsScopeRegular: |
200 return &(i->second->settings); | 202 return &(i->second->settings); |
201 case kExtensionPrefsScopeIncognitoPersistent: | 203 case kExtensionPrefsScopeIncognitoPersistent: |
202 return &(i->second->incognito_persistent_settings); | 204 return &(i->second->incognito_persistent_settings); |
203 case kExtensionPrefsScopeIncognitoSessionOnly: | 205 case kExtensionPrefsScopeIncognitoSessionOnly: |
204 return &(i->second->incognito_session_only_settings); | 206 return &(i->second->incognito_session_only_settings); |
205 } | 207 } |
206 } | 208 } |
207 return NULL; | 209 return NULL; |
208 } | 210 } |
209 | 211 |
210 void ExtensionContentSettingsStore::ClearContentSettingsForExtension( | 212 void ContentSettingsStore::ClearContentSettingsForExtension( |
211 const std::string& ext_id, | 213 const std::string& ext_id, |
212 ExtensionPrefsScope scope) { | 214 ExtensionPrefsScope scope) { |
213 bool notify = false; | 215 bool notify = false; |
214 { | 216 { |
215 base::AutoLock lock(lock_); | 217 base::AutoLock lock(lock_); |
216 OriginIdentifierValueMap* map = GetValueMap(ext_id, scope); | 218 OriginIdentifierValueMap* map = GetValueMap(ext_id, scope); |
217 notify = !map->empty(); | 219 notify = !map->empty(); |
218 map->clear(); | 220 map->clear(); |
219 } | 221 } |
220 if (notify) { | 222 if (notify) { |
221 NotifyOfContentSettingChanged(ext_id, scope != kExtensionPrefsScopeRegular); | 223 NotifyOfContentSettingChanged(ext_id, scope != kExtensionPrefsScopeRegular); |
222 } | 224 } |
223 } | 225 } |
224 | 226 |
225 base::ListValue* ExtensionContentSettingsStore::GetSettingsForExtension( | 227 base::ListValue* ContentSettingsStore::GetSettingsForExtension( |
226 const std::string& extension_id, | 228 const std::string& extension_id, |
227 ExtensionPrefsScope scope) const { | 229 ExtensionPrefsScope scope) const { |
228 base::AutoLock lock(lock_); | 230 base::AutoLock lock(lock_); |
229 const OriginIdentifierValueMap* map = GetValueMap(extension_id, scope); | 231 const OriginIdentifierValueMap* map = GetValueMap(extension_id, scope); |
230 if (!map) | 232 if (!map) |
231 return NULL; | 233 return NULL; |
232 base::ListValue* settings = new base::ListValue(); | 234 base::ListValue* settings = new base::ListValue(); |
233 OriginIdentifierValueMap::EntryMap::const_iterator it; | 235 OriginIdentifierValueMap::EntryMap::const_iterator it; |
234 for (it = map->begin(); it != map->end(); ++it) { | 236 for (it = map->begin(); it != map->end(); ++it) { |
235 scoped_ptr<RuleIterator> rule_iterator( | 237 scoped_ptr<RuleIterator> rule_iterator( |
(...skipping 16 matching lines...) Expand all Loading... |
252 DCHECK_NE(CONTENT_SETTING_DEFAULT, content_setting); | 254 DCHECK_NE(CONTENT_SETTING_DEFAULT, content_setting); |
253 setting_dict->SetString( | 255 setting_dict->SetString( |
254 keys::kContentSettingKey, | 256 keys::kContentSettingKey, |
255 helpers::ContentSettingToString(content_setting)); | 257 helpers::ContentSettingToString(content_setting)); |
256 settings->Append(setting_dict); | 258 settings->Append(setting_dict); |
257 } | 259 } |
258 } | 260 } |
259 return settings; | 261 return settings; |
260 } | 262 } |
261 | 263 |
262 void ExtensionContentSettingsStore::SetExtensionContentSettingsFromList( | 264 void ContentSettingsStore::SetExtensionContentSettingFromList( |
263 const std::string& extension_id, | 265 const std::string& extension_id, |
264 const base::ListValue* list, | 266 const base::ListValue* list, |
265 ExtensionPrefsScope scope) { | 267 ExtensionPrefsScope scope) { |
266 for (base::ListValue::const_iterator it = list->begin(); | 268 for (base::ListValue::const_iterator it = list->begin(); |
267 it != list->end(); ++it) { | 269 it != list->end(); ++it) { |
268 if ((*it)->GetType() != Value::TYPE_DICTIONARY) { | 270 if ((*it)->GetType() != Value::TYPE_DICTIONARY) { |
269 NOTREACHED(); | 271 NOTREACHED(); |
270 continue; | 272 continue; |
271 } | 273 } |
272 base::DictionaryValue* dict = static_cast<base::DictionaryValue*>(*it); | 274 base::DictionaryValue* dict = static_cast<base::DictionaryValue*>(*it); |
(...skipping 28 matching lines...) Expand all Loading... |
301 SetExtensionContentSetting(extension_id, | 303 SetExtensionContentSetting(extension_id, |
302 primary_pattern, | 304 primary_pattern, |
303 secondary_pattern, | 305 secondary_pattern, |
304 content_settings_type, | 306 content_settings_type, |
305 resource_identifier, | 307 resource_identifier, |
306 setting, | 308 setting, |
307 scope); | 309 scope); |
308 } | 310 } |
309 } | 311 } |
310 | 312 |
311 void ExtensionContentSettingsStore::AddObserver(Observer* observer) { | 313 void ContentSettingsStore::AddObserver(Observer* observer) { |
312 DCHECK(OnCorrectThread()); | 314 DCHECK(OnCorrectThread()); |
313 observers_.AddObserver(observer); | 315 observers_.AddObserver(observer); |
314 } | 316 } |
315 | 317 |
316 void ExtensionContentSettingsStore::RemoveObserver(Observer* observer) { | 318 void ContentSettingsStore::RemoveObserver(Observer* observer) { |
317 DCHECK(OnCorrectThread()); | 319 DCHECK(OnCorrectThread()); |
318 observers_.RemoveObserver(observer); | 320 observers_.RemoveObserver(observer); |
319 } | 321 } |
320 | 322 |
321 void ExtensionContentSettingsStore::NotifyOfContentSettingChanged( | 323 void ContentSettingsStore::NotifyOfContentSettingChanged( |
322 const std::string& extension_id, | 324 const std::string& extension_id, |
323 bool incognito) { | 325 bool incognito) { |
324 FOR_EACH_OBSERVER( | 326 FOR_EACH_OBSERVER( |
325 ExtensionContentSettingsStore::Observer, | 327 ContentSettingsStore::Observer, |
326 observers_, | 328 observers_, |
327 OnContentSettingChanged(extension_id, incognito)); | 329 OnContentSettingChanged(extension_id, incognito)); |
328 } | 330 } |
329 | 331 |
330 bool ExtensionContentSettingsStore::OnCorrectThread() { | 332 bool ContentSettingsStore::OnCorrectThread() { |
331 // If there is no UI thread, we're most likely in a unit test. | 333 // If there is no UI thread, we're most likely in a unit test. |
332 return !BrowserThread::IsWellKnownThread(BrowserThread::UI) || | 334 return !BrowserThread::IsWellKnownThread(BrowserThread::UI) || |
333 BrowserThread::CurrentlyOn(BrowserThread::UI); | 335 BrowserThread::CurrentlyOn(BrowserThread::UI); |
334 } | 336 } |
335 | 337 |
336 ExtensionContentSettingsStore::ExtensionEntryMap::iterator | 338 ContentSettingsStore::ExtensionEntryMap::iterator |
337 ExtensionContentSettingsStore::FindEntry(const std::string& ext_id) { | 339 ContentSettingsStore::FindEntry(const std::string& ext_id) { |
338 ExtensionEntryMap::iterator i; | 340 ExtensionEntryMap::iterator i; |
339 for (i = entries_.begin(); i != entries_.end(); ++i) { | 341 for (i = entries_.begin(); i != entries_.end(); ++i) { |
340 if (i->second->id == ext_id) | 342 if (i->second->id == ext_id) |
341 return i; | 343 return i; |
342 } | 344 } |
343 return entries_.end(); | 345 return entries_.end(); |
344 } | 346 } |
345 | 347 |
346 ExtensionContentSettingsStore::ExtensionEntryMap::const_iterator | 348 ContentSettingsStore::ExtensionEntryMap::const_iterator |
347 ExtensionContentSettingsStore::FindEntry(const std::string& ext_id) const { | 349 ContentSettingsStore::FindEntry(const std::string& ext_id) const { |
348 ExtensionEntryMap::const_iterator i; | 350 ExtensionEntryMap::const_iterator i; |
349 for (i = entries_.begin(); i != entries_.end(); ++i) { | 351 for (i = entries_.begin(); i != entries_.end(); ++i) { |
350 if (i->second->id == ext_id) | 352 if (i->second->id == ext_id) |
351 return i; | 353 return i; |
352 } | 354 } |
353 return entries_.end(); | 355 return entries_.end(); |
354 } | 356 } |
| 357 |
| 358 } // namespace extensions |
OLD | NEW |