Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: chrome/browser/extensions/extension_content_settings_store.cc

Issue 10381097: Move content settings extension API to content_settings dir. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: fixed conflict Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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_content_settings_store.h"
6
7 #include <set>
8
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/memory/scoped_vector.h"
12 #include "base/stl_util.h"
13 #include "base/values.h"
14 #include "chrome/browser/content_settings/content_settings_origin_identifier_val ue_map.h"
15 #include "chrome/browser/content_settings/content_settings_rule.h"
16 #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"
20
21 namespace helpers = extension_content_settings_helpers;
22 namespace keys = extension_content_settings_api_constants;
23
24 using content::BrowserThread;
25 using content_settings::ConcatenationIterator;
26 using content_settings::Rule;
27 using content_settings::RuleIterator;
28 using content_settings::OriginIdentifierValueMap;
29 using content_settings::ResourceIdentifier;
30 using content_settings::ValueToContentSetting;
31
32 struct ExtensionContentSettingsStore::ExtensionEntry {
33 // Extension id
34 std::string id;
35 // Whether extension is enabled in the profile.
36 bool enabled;
37 // Content settings.
38 OriginIdentifierValueMap settings;
39 // Persistent incognito content settings.
40 OriginIdentifierValueMap incognito_persistent_settings;
41 // Session-only incognito content settings.
42 OriginIdentifierValueMap incognito_session_only_settings;
43 };
44
45 ExtensionContentSettingsStore::ExtensionContentSettingsStore() {
46 DCHECK(OnCorrectThread());
47 }
48
49 ExtensionContentSettingsStore::~ExtensionContentSettingsStore() {
50 STLDeleteValues(&entries_);
51 }
52
53 RuleIterator* ExtensionContentSettingsStore::GetRuleIterator(
54 ContentSettingsType type,
55 const content_settings::ResourceIdentifier& identifier,
56 bool incognito) const {
57 ScopedVector<RuleIterator> iterators;
58 // Iterate the extensions based on install time (last installed extensions
59 // first).
60 ExtensionEntryMap::const_reverse_iterator entry;
61
62 // The individual |RuleIterators| shouldn't lock; pass |lock_| to the
63 // |ConcatenationIterator| in a locked state.
64 scoped_ptr<base::AutoLock> auto_lock(new base::AutoLock(lock_));
65
66 for (entry = entries_.rbegin(); entry != entries_.rend(); ++entry) {
67 if (!entry->second->enabled)
68 continue;
69
70 if (incognito) {
71 iterators.push_back(
72 entry->second->incognito_session_only_settings.GetRuleIterator(
73 type,
74 identifier,
75 NULL));
76 iterators.push_back(
77 entry->second->incognito_persistent_settings.GetRuleIterator(
78 type,
79 identifier,
80 NULL));
81 } else {
82 iterators.push_back(
83 entry->second->settings.GetRuleIterator(type, identifier, NULL));
84 }
85 }
86 return new ConcatenationIterator(&iterators, auto_lock.release());
87 }
88
89 void ExtensionContentSettingsStore::SetExtensionContentSetting(
90 const std::string& ext_id,
91 const ContentSettingsPattern& primary_pattern,
92 const ContentSettingsPattern& secondary_pattern,
93 ContentSettingsType type,
94 const content_settings::ResourceIdentifier& identifier,
95 ContentSetting setting,
96 ExtensionPrefsScope scope) {
97 {
98 base::AutoLock lock(lock_);
99 OriginIdentifierValueMap* map = GetValueMap(ext_id, scope);
100 if (setting == CONTENT_SETTING_DEFAULT) {
101 map->DeleteValue(primary_pattern, secondary_pattern, type, identifier);
102 } else {
103 map->SetValue(primary_pattern, secondary_pattern, type, identifier,
104 base::Value::CreateIntegerValue(setting));
105 }
106 }
107
108 // Send notification that content settings changed.
109 // TODO(markusheintz): Notifications should only be sent if the set content
110 // setting is effective and not hidden by another setting of another
111 // extension installed more recently.
112 NotifyOfContentSettingChanged(ext_id,
113 scope != kExtensionPrefsScopeRegular);
114 }
115
116 void ExtensionContentSettingsStore::RegisterExtension(
117 const std::string& ext_id,
118 const base::Time& install_time,
119 bool is_enabled) {
120 base::AutoLock lock(lock_);
121 ExtensionEntryMap::iterator i = FindEntry(ext_id);
122 if (i != entries_.end()) {
123 delete i->second;
124 entries_.erase(i);
125 }
126
127 ExtensionEntry* entry = new ExtensionEntry;
128 entry->id = ext_id;
129 entry->enabled = is_enabled;
130 entries_.insert(std::make_pair(install_time, entry));
131 }
132
133 void ExtensionContentSettingsStore::UnregisterExtension(
134 const std::string& ext_id) {
135 bool notify = false;
136 bool notify_incognito = false;
137 {
138 base::AutoLock lock(lock_);
139 ExtensionEntryMap::iterator i = FindEntry(ext_id);
140 if (i == entries_.end())
141 return;
142 notify = !i->second->settings.empty();
143 notify_incognito = !i->second->incognito_persistent_settings.empty() ||
144 !i->second->incognito_session_only_settings.empty();
145
146 delete i->second;
147 entries_.erase(i);
148 }
149 if (notify)
150 NotifyOfContentSettingChanged(ext_id, false);
151 if (notify_incognito)
152 NotifyOfContentSettingChanged(ext_id, true);
153 }
154
155 void ExtensionContentSettingsStore::SetExtensionState(
156 const std::string& ext_id, bool is_enabled) {
157 bool notify = false;
158 bool notify_incognito = false;
159 {
160 base::AutoLock lock(lock_);
161 ExtensionEntryMap::const_iterator i = FindEntry(ext_id);
162 if (i == entries_.end())
163 return;
164 notify = !i->second->settings.empty();
165 notify_incognito = !i->second->incognito_persistent_settings.empty() ||
166 !i->second->incognito_session_only_settings.empty();
167
168 i->second->enabled = is_enabled;
169 }
170 if (notify)
171 NotifyOfContentSettingChanged(ext_id, false);
172 if (notify_incognito)
173 NotifyOfContentSettingChanged(ext_id, true);
174 }
175
176 OriginIdentifierValueMap* ExtensionContentSettingsStore::GetValueMap(
177 const std::string& ext_id,
178 ExtensionPrefsScope scope) {
179 ExtensionEntryMap::const_iterator i = FindEntry(ext_id);
180 if (i != entries_.end()) {
181 switch (scope) {
182 case kExtensionPrefsScopeRegular:
183 return &(i->second->settings);
184 case kExtensionPrefsScopeIncognitoPersistent:
185 return &(i->second->incognito_persistent_settings);
186 case kExtensionPrefsScopeIncognitoSessionOnly:
187 return &(i->second->incognito_session_only_settings);
188 }
189 }
190 return NULL;
191 }
192
193 const OriginIdentifierValueMap* ExtensionContentSettingsStore::GetValueMap(
194 const std::string& ext_id,
195 ExtensionPrefsScope scope) const {
196 ExtensionEntryMap::const_iterator i = FindEntry(ext_id);
197 if (i != entries_.end()) {
198 switch (scope) {
199 case kExtensionPrefsScopeRegular:
200 return &(i->second->settings);
201 case kExtensionPrefsScopeIncognitoPersistent:
202 return &(i->second->incognito_persistent_settings);
203 case kExtensionPrefsScopeIncognitoSessionOnly:
204 return &(i->second->incognito_session_only_settings);
205 }
206 }
207 return NULL;
208 }
209
210 void ExtensionContentSettingsStore::ClearContentSettingsForExtension(
211 const std::string& ext_id,
212 ExtensionPrefsScope scope) {
213 bool notify = false;
214 {
215 base::AutoLock lock(lock_);
216 OriginIdentifierValueMap* map = GetValueMap(ext_id, scope);
217 notify = !map->empty();
218 map->clear();
219 }
220 if (notify) {
221 NotifyOfContentSettingChanged(ext_id, scope != kExtensionPrefsScopeRegular);
222 }
223 }
224
225 base::ListValue* ExtensionContentSettingsStore::GetSettingsForExtension(
226 const std::string& extension_id,
227 ExtensionPrefsScope scope) const {
228 base::AutoLock lock(lock_);
229 const OriginIdentifierValueMap* map = GetValueMap(extension_id, scope);
230 if (!map)
231 return NULL;
232 base::ListValue* settings = new base::ListValue();
233 OriginIdentifierValueMap::EntryMap::const_iterator it;
234 for (it = map->begin(); it != map->end(); ++it) {
235 scoped_ptr<RuleIterator> rule_iterator(
236 map->GetRuleIterator(it->first.content_type,
237 it->first.resource_identifier,
238 NULL)); // We already hold the lock.
239 while (rule_iterator->HasNext()) {
240 const Rule& rule = rule_iterator->Next();
241 base::DictionaryValue* setting_dict = new base::DictionaryValue();
242 setting_dict->SetString(keys::kPrimaryPatternKey,
243 rule.primary_pattern.ToString());
244 setting_dict->SetString(keys::kSecondaryPatternKey,
245 rule.secondary_pattern.ToString());
246 setting_dict->SetString(
247 keys::kContentSettingsTypeKey,
248 helpers::ContentSettingsTypeToString(it->first.content_type));
249 setting_dict->SetString(keys::kResourceIdentifierKey,
250 it->first.resource_identifier);
251 ContentSetting content_setting = ValueToContentSetting(rule.value.get());
252 DCHECK_NE(CONTENT_SETTING_DEFAULT, content_setting);
253 setting_dict->SetString(
254 keys::kContentSettingKey,
255 helpers::ContentSettingToString(content_setting));
256 settings->Append(setting_dict);
257 }
258 }
259 return settings;
260 }
261
262 void ExtensionContentSettingsStore::SetExtensionContentSettingsFromList(
263 const std::string& extension_id,
264 const base::ListValue* list,
265 ExtensionPrefsScope scope) {
266 for (base::ListValue::const_iterator it = list->begin();
267 it != list->end(); ++it) {
268 if ((*it)->GetType() != Value::TYPE_DICTIONARY) {
269 NOTREACHED();
270 continue;
271 }
272 base::DictionaryValue* dict = static_cast<base::DictionaryValue*>(*it);
273 std::string primary_pattern_str;
274 dict->GetString(keys::kPrimaryPatternKey, &primary_pattern_str);
275 ContentSettingsPattern primary_pattern =
276 ContentSettingsPattern::FromString(primary_pattern_str);
277 DCHECK(primary_pattern.IsValid());
278
279 std::string secondary_pattern_str;
280 dict->GetString(keys::kSecondaryPatternKey, &secondary_pattern_str);
281 ContentSettingsPattern secondary_pattern =
282 ContentSettingsPattern::FromString(secondary_pattern_str);
283 DCHECK(secondary_pattern.IsValid());
284
285 std::string content_settings_type_str;
286 dict->GetString(keys::kContentSettingsTypeKey, &content_settings_type_str);
287 ContentSettingsType content_settings_type =
288 helpers::StringToContentSettingsType(content_settings_type_str);
289 DCHECK_NE(CONTENT_SETTINGS_TYPE_DEFAULT, content_settings_type);
290
291 std::string resource_identifier;
292 dict->GetString(keys::kResourceIdentifierKey, &resource_identifier);
293
294 std::string content_setting_string;
295 dict->GetString(keys::kContentSettingKey, &content_setting_string);
296 ContentSetting setting = CONTENT_SETTING_DEFAULT;
297 bool result =
298 helpers::StringToContentSetting(content_setting_string, &setting);
299 DCHECK(result);
300
301 SetExtensionContentSetting(extension_id,
302 primary_pattern,
303 secondary_pattern,
304 content_settings_type,
305 resource_identifier,
306 setting,
307 scope);
308 }
309 }
310
311 void ExtensionContentSettingsStore::AddObserver(Observer* observer) {
312 DCHECK(OnCorrectThread());
313 observers_.AddObserver(observer);
314 }
315
316 void ExtensionContentSettingsStore::RemoveObserver(Observer* observer) {
317 DCHECK(OnCorrectThread());
318 observers_.RemoveObserver(observer);
319 }
320
321 void ExtensionContentSettingsStore::NotifyOfContentSettingChanged(
322 const std::string& extension_id,
323 bool incognito) {
324 FOR_EACH_OBSERVER(
325 ExtensionContentSettingsStore::Observer,
326 observers_,
327 OnContentSettingChanged(extension_id, incognito));
328 }
329
330 bool ExtensionContentSettingsStore::OnCorrectThread() {
331 // If there is no UI thread, we're most likely in a unit test.
332 return !BrowserThread::IsWellKnownThread(BrowserThread::UI) ||
333 BrowserThread::CurrentlyOn(BrowserThread::UI);
334 }
335
336 ExtensionContentSettingsStore::ExtensionEntryMap::iterator
337 ExtensionContentSettingsStore::FindEntry(const std::string& ext_id) {
338 ExtensionEntryMap::iterator i;
339 for (i = entries_.begin(); i != entries_.end(); ++i) {
340 if (i->second->id == ext_id)
341 return i;
342 }
343 return entries_.end();
344 }
345
346 ExtensionContentSettingsStore::ExtensionEntryMap::const_iterator
347 ExtensionContentSettingsStore::FindEntry(const std::string& ext_id) const {
348 ExtensionEntryMap::const_iterator i;
349 for (i = entries_.begin(); i != entries_.end(); ++i) {
350 if (i->second->id == ext_id)
351 return i;
352 }
353 return entries_.end();
354 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698