Add abhijeet.k@samsung.com to AUTHORS list.
[chromium-blink-merge.git] / components / content_settings / core / browser / content_settings_pref.cc
blob7cfd31a4aaacdc32a4452c5b1ea49add65dc6492
1 // Copyright 2015 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 "components/content_settings/core/browser/content_settings_pref.h"
7 #include "base/auto_reset.h"
8 #include "base/bind.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/metrics/histogram.h"
11 #include "base/prefs/scoped_user_pref_update.h"
12 #include "base/strings/string_split.h"
13 #include "base/time/clock.h"
14 #include "components/content_settings/core/browser/content_settings_rule.h"
15 #include "components/content_settings/core/browser/content_settings_utils.h"
16 #include "components/content_settings/core/browser/host_content_settings_map.h"
17 #include "components/content_settings/core/common/content_settings.h"
18 #include "components/content_settings/core/common/content_settings_pattern.h"
19 #include "components/content_settings/core/common/pref_names.h"
20 #include "url/gurl.h"
22 namespace {
24 const char kSettingPath[] = "setting";
25 const char kPerResourceIdentifierPrefName[] = "per_resource";
26 const char kPerPluginPrefName[] = "per_plugin";
27 const char kLastUsed[] = "last_used";
29 ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type,
30 ContentSetting setting) {
31 if (content_type == CONTENT_SETTINGS_TYPE_COOKIES &&
32 setting == CONTENT_SETTING_ASK) {
33 return CONTENT_SETTING_BLOCK;
35 return setting;
38 // If the given content type supports resource identifiers in user preferences,
39 // returns true and sets |pref_key| to the key in the content settings
40 // dictionary under which per-resource content settings are stored.
41 // Otherwise, returns false.
42 bool SupportsResourceIdentifiers(ContentSettingsType content_type) {
43 return content_type == CONTENT_SETTINGS_TYPE_PLUGINS;
46 } // namespace
48 namespace content_settings {
50 ContentSettingsPref::ContentSettingsPref(
51 ContentSettingsType content_type,
52 PrefService* prefs,
53 PrefChangeRegistrar* registrar,
54 const char* pref_name,
55 bool incognito,
56 bool* updating_old_preferences_flag,
57 NotifyObserversCallback notify_callback)
58 : content_type_(content_type),
59 prefs_(prefs),
60 registrar_(registrar),
61 pref_name_(pref_name),
62 is_incognito_(incognito),
63 updating_preferences_(false),
64 updating_old_preferences_(updating_old_preferences_flag),
65 notify_callback_(notify_callback) {
66 DCHECK(prefs_);
68 // If the migration hasn't happened yet, or if this content setting
69 // is syncable, the parent |PrefProvider| is going to copy the contents
70 // of the old preference to this new preference. There is no need
71 // to initialize this preference separately (in fact, in the case
72 // of migration, we would be writing the empty new preference back to the
73 // old one, erasing it).
74 if (prefs_->GetBoolean(prefs::kMigratedContentSettingsPatternPairs) &&
75 !IsContentSettingsTypeSyncable(content_type_)) {
76 ReadContentSettingsFromPrefAndWriteToOldPref();
79 registrar_->Add(
80 pref_name_,
81 base::Bind(&ContentSettingsPref::OnPrefChanged, base::Unretained(this)));
84 ContentSettingsPref::~ContentSettingsPref() {
87 RuleIterator* ContentSettingsPref::GetRuleIterator(
88 const ResourceIdentifier& resource_identifier,
89 bool incognito) const {
90 if (incognito)
91 return incognito_value_map_.GetRuleIterator(content_type_,
92 resource_identifier,
93 &lock_);
94 return value_map_.GetRuleIterator(content_type_, resource_identifier, &lock_);
97 bool ContentSettingsPref::SetWebsiteSetting(
98 const ContentSettingsPattern& primary_pattern,
99 const ContentSettingsPattern& secondary_pattern,
100 const ResourceIdentifier& resource_identifier,
101 base::Value* in_value) {
102 DCHECK(thread_checker_.CalledOnValidThread());
103 DCHECK(prefs_);
104 DCHECK(primary_pattern != ContentSettingsPattern::Wildcard() ||
105 secondary_pattern != ContentSettingsPattern::Wildcard() ||
106 !resource_identifier.empty());
108 // At this point take the ownership of the |in_value|.
109 scoped_ptr<base::Value> value(in_value);
111 // Update in memory value map.
112 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
113 if (!is_incognito_)
114 map_to_modify = &value_map_;
117 base::AutoLock auto_lock(lock_);
118 if (value.get()) {
119 map_to_modify->SetValue(
120 primary_pattern,
121 secondary_pattern,
122 content_type_,
123 resource_identifier,
124 value->DeepCopy());
125 } else {
126 map_to_modify->DeleteValue(
127 primary_pattern,
128 secondary_pattern,
129 content_type_,
130 resource_identifier);
133 // Update the content settings preference.
134 if (!is_incognito_) {
135 UpdatePref(primary_pattern,
136 secondary_pattern,
137 resource_identifier,
138 value.get());
139 if (IsContentSettingsTypeSyncable(content_type_)) {
140 UpdateOldPref(primary_pattern,
141 secondary_pattern,
142 resource_identifier,
143 value.get());
147 notify_callback_.Run(
148 primary_pattern, secondary_pattern, content_type_, resource_identifier);
150 return true;
153 void ContentSettingsPref::ClearAllContentSettingsRules() {
154 DCHECK(thread_checker_.CalledOnValidThread());
155 DCHECK(prefs_);
157 OriginIdentifierValueMap* map_to_modify = &incognito_value_map_;
158 if (!is_incognito_)
159 map_to_modify = &value_map_;
161 std::vector<Rule> rules_to_delete;
163 base::AutoLock auto_lock(lock_);
164 scoped_ptr<RuleIterator> rule_iterator(
165 map_to_modify->GetRuleIterator(content_type_, std::string(), NULL));
166 // Copy the rules; we cannot call |UpdatePref| while holding |lock_|.
167 while (rule_iterator->HasNext())
168 rules_to_delete.push_back(rule_iterator->Next());
170 map_to_modify->DeleteValues(content_type_, std::string());
173 for (std::vector<Rule>::const_iterator it = rules_to_delete.begin();
174 it != rules_to_delete.end(); ++it) {
175 UpdatePref(it->primary_pattern,
176 it->secondary_pattern,
177 std::string(),
178 NULL);
179 if (IsContentSettingsTypeSyncable(content_type_)) {
180 UpdateOldPref(it->primary_pattern,
181 it->secondary_pattern,
182 std::string(),
183 NULL);
186 notify_callback_.Run(ContentSettingsPattern(),
187 ContentSettingsPattern(),
188 content_type_,
189 std::string());
192 void ContentSettingsPref::UpdateLastUsage(
193 const ContentSettingsPattern& primary_pattern,
194 const ContentSettingsPattern& secondary_pattern,
195 base::Clock* clock) {
196 // Don't write if in incognito.
197 if (is_incognito_) {
198 return;
201 // Ensure that |lock_| is not held by this thread, since this function will
202 // send out notifications (by |~DictionaryPrefUpdate|).
203 AssertLockNotHeld();
205 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
207 DictionaryPrefUpdate update(prefs_, pref_name_);
208 base::DictionaryValue* pattern_pairs_settings = update.Get();
210 std::string pattern_str(
211 CreatePatternString(primary_pattern, secondary_pattern));
212 base::DictionaryValue* settings_dictionary = NULL;
213 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
214 pattern_str, &settings_dictionary);
216 if (!found) {
217 settings_dictionary = new base::DictionaryValue;
218 pattern_pairs_settings->SetWithoutPathExpansion(pattern_str,
219 settings_dictionary);
222 settings_dictionary->SetWithoutPathExpansion(
223 kLastUsed, new base::FundamentalValue(clock->Now().ToDoubleT()));
227 base::Time ContentSettingsPref::GetLastUsage(
228 const ContentSettingsPattern& primary_pattern,
229 const ContentSettingsPattern& secondary_pattern) {
230 const base::DictionaryValue* pattern_pairs_settings =
231 prefs_->GetDictionary(pref_name_);
232 std::string pattern_str(
233 CreatePatternString(primary_pattern, secondary_pattern));
235 const base::DictionaryValue* settings_dictionary = NULL;
236 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
237 pattern_str, &settings_dictionary);
239 if (!found)
240 return base::Time();
242 double last_used_time;
243 found = settings_dictionary->GetDoubleWithoutPathExpansion(
244 kLastUsed, &last_used_time);
246 if (!found)
247 return base::Time();
249 return base::Time::FromDoubleT(last_used_time);
252 size_t ContentSettingsPref::GetNumExceptions() {
253 return value_map_.size();
256 void ContentSettingsPref::ReadContentSettingsFromPrefAndWriteToOldPref() {
257 // Clear the old preference, so we can copy the exceptions from the new
258 // preference into it. Note that copying in this direction is disallowed
259 // in incognito, to avoid the echo effect: New preference -> PrefProvider ->
260 // Old preference -> Incognito PrefProvider -> New preference -> etc.
261 if (!is_incognito_ && IsContentSettingsTypeSyncable(content_type_))
262 ClearOldPreference();
264 // |DictionaryPrefUpdate| sends out notifications when destructed. This
265 // construction order ensures |AutoLock| gets destroyed first and |lock_| is
266 // not held when the notifications are sent. Also, |auto_reset| must be still
267 // valid when the notifications are sent, so that |Observe| skips the
268 // notification.
269 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
270 DictionaryPrefUpdate update(prefs_, pref_name_);
271 base::AutoLock auto_lock(lock_);
273 const base::DictionaryValue* all_settings_dictionary =
274 prefs_->GetDictionary(pref_name_);
276 value_map_.clear();
278 // Careful: The returned value could be NULL if the pref has never been set.
279 if (!all_settings_dictionary)
280 return;
282 base::DictionaryValue* mutable_settings;
283 scoped_ptr<base::DictionaryValue> mutable_settings_scope;
285 if (!is_incognito_) {
286 mutable_settings = update.Get();
287 } else {
288 // Create copy as we do not want to persist anything in OTR prefs.
289 mutable_settings = all_settings_dictionary->DeepCopy();
290 mutable_settings_scope.reset(mutable_settings);
292 // Convert all Unicode patterns into punycode form, then read.
293 CanonicalizeContentSettingsExceptions(mutable_settings);
295 size_t cookies_block_exception_count = 0;
296 size_t cookies_allow_exception_count = 0;
297 size_t cookies_session_only_exception_count = 0;
298 for (base::DictionaryValue::Iterator i(*mutable_settings); !i.IsAtEnd();
299 i.Advance()) {
300 const std::string& pattern_str(i.key());
301 std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
302 ParsePatternString(pattern_str);
303 if (!pattern_pair.first.IsValid() ||
304 !pattern_pair.second.IsValid()) {
305 // TODO: Change this to DFATAL when crbug.com/132659 is fixed.
306 LOG(ERROR) << "Invalid pattern strings: " << pattern_str;
307 continue;
310 // Get settings dictionary for the current pattern string, and read
311 // settings from the dictionary.
312 const base::DictionaryValue* settings_dictionary = NULL;
313 bool is_dictionary = i.value().GetAsDictionary(&settings_dictionary);
314 DCHECK(is_dictionary);
316 if (SupportsResourceIdentifiers(content_type_)) {
317 const base::DictionaryValue* resource_dictionary = NULL;
318 if (settings_dictionary->GetDictionary(
319 kPerResourceIdentifierPrefName, &resource_dictionary)) {
320 for (base::DictionaryValue::Iterator j(*resource_dictionary);
321 !j.IsAtEnd();
322 j.Advance()) {
323 const std::string& resource_identifier(j.key());
324 int setting = CONTENT_SETTING_DEFAULT;
325 bool is_integer = j.value().GetAsInteger(&setting);
326 DCHECK(is_integer);
327 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
328 scoped_ptr<base::Value> setting_ptr(
329 new base::FundamentalValue(setting));
330 value_map_.SetValue(pattern_pair.first,
331 pattern_pair.second,
332 content_type_,
333 resource_identifier,
334 setting_ptr->DeepCopy());
335 if (!is_incognito_ && IsContentSettingsTypeSyncable(content_type_)) {
336 UpdateOldPref(pattern_pair.first,
337 pattern_pair.second,
338 resource_identifier,
339 setting_ptr.get());
344 base::Value* value = NULL;
345 if (HostContentSettingsMap::ContentTypeHasCompoundValue(content_type_)) {
346 const base::DictionaryValue* setting = NULL;
347 // TODO(xians): Handle the non-dictionary types.
348 if (settings_dictionary->GetDictionaryWithoutPathExpansion(
349 kSettingPath, &setting)) {
350 DCHECK(!setting->empty());
351 value = setting->DeepCopy();
353 } else {
354 int setting = CONTENT_SETTING_DEFAULT;
355 if (settings_dictionary->GetIntegerWithoutPathExpansion(
356 kSettingPath, &setting)) {
357 DCHECK_NE(CONTENT_SETTING_DEFAULT, setting);
358 setting = FixObsoleteCookiePromptMode(content_type_,
359 ContentSetting(setting));
360 value = new base::FundamentalValue(setting);
364 if (value != NULL) {
365 scoped_ptr<base::Value> value_ptr(value);
366 value_map_.SetValue(pattern_pair.first,
367 pattern_pair.second,
368 content_type_,
369 ResourceIdentifier(),
370 value->DeepCopy());
371 if (!is_incognito_ && IsContentSettingsTypeSyncable(content_type_)) {
372 UpdateOldPref(pattern_pair.first,
373 pattern_pair.second,
374 ResourceIdentifier(),
375 value_ptr.get());
377 if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) {
378 ContentSetting s = ValueToContentSetting(value);
379 switch (s) {
380 case CONTENT_SETTING_ALLOW :
381 ++cookies_allow_exception_count;
382 break;
383 case CONTENT_SETTING_BLOCK :
384 ++cookies_block_exception_count;
385 break;
386 case CONTENT_SETTING_SESSION_ONLY :
387 ++cookies_session_only_exception_count;
388 break;
389 default:
390 NOTREACHED();
391 break;
398 if (content_type_ == CONTENT_SETTINGS_TYPE_COOKIES) {
399 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfBlockCookiesExceptions",
400 cookies_block_exception_count);
401 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfAllowCookiesExceptions",
402 cookies_allow_exception_count);
403 UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfSessionOnlyCookiesExceptions",
404 cookies_session_only_exception_count);
408 void ContentSettingsPref::OnPrefChanged() {
409 DCHECK(thread_checker_.CalledOnValidThread());
411 if (updating_preferences_)
412 return;
414 ReadContentSettingsFromPrefAndWriteToOldPref();
416 notify_callback_.Run(ContentSettingsPattern(),
417 ContentSettingsPattern(),
418 content_type_,
419 std::string());
422 void ContentSettingsPref::UpdatePref(
423 const ContentSettingsPattern& primary_pattern,
424 const ContentSettingsPattern& secondary_pattern,
425 const ResourceIdentifier& resource_identifier,
426 const base::Value* value) {
427 // Ensure that |lock_| is not held by this thread, since this function will
428 // send out notifications (by |~DictionaryPrefUpdate|).
429 AssertLockNotHeld();
431 base::AutoReset<bool> auto_reset(&updating_preferences_, true);
433 DictionaryPrefUpdate update(prefs_, pref_name_);
434 base::DictionaryValue* pattern_pairs_settings = update.Get();
436 // Get settings dictionary for the given patterns.
437 std::string pattern_str(CreatePatternString(primary_pattern,
438 secondary_pattern));
439 base::DictionaryValue* settings_dictionary = NULL;
440 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
441 pattern_str, &settings_dictionary);
443 if (!found && value) {
444 settings_dictionary = new base::DictionaryValue;
445 pattern_pairs_settings->SetWithoutPathExpansion(
446 pattern_str, settings_dictionary);
449 if (settings_dictionary) {
450 if (SupportsResourceIdentifiers(content_type_) &&
451 !resource_identifier.empty()) {
452 base::DictionaryValue* resource_dictionary = NULL;
453 found = settings_dictionary->GetDictionary(
454 kPerResourceIdentifierPrefName, &resource_dictionary);
455 if (!found) {
456 if (value == NULL)
457 return; // Nothing to remove. Exit early.
458 resource_dictionary = new base::DictionaryValue;
459 settings_dictionary->Set(
460 kPerResourceIdentifierPrefName, resource_dictionary);
462 // Update resource dictionary.
463 if (value == NULL) {
464 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
465 NULL);
466 if (resource_dictionary->empty()) {
467 settings_dictionary->RemoveWithoutPathExpansion(
468 kPerResourceIdentifierPrefName, NULL);
470 } else {
471 resource_dictionary->SetWithoutPathExpansion(
472 resource_identifier, value->DeepCopy());
474 } else {
475 // Update settings dictionary.
476 if (value == NULL) {
477 settings_dictionary->RemoveWithoutPathExpansion(kSettingPath, NULL);
478 settings_dictionary->RemoveWithoutPathExpansion(kLastUsed, NULL);
479 } else {
480 settings_dictionary->SetWithoutPathExpansion(
481 kSettingPath, value->DeepCopy());
484 // Remove the settings dictionary if it is empty.
485 if (settings_dictionary->empty()) {
486 pattern_pairs_settings->RemoveWithoutPathExpansion(
487 pattern_str, NULL);
493 void ContentSettingsPref::UpdateOldPref(
494 const ContentSettingsPattern& primary_pattern,
495 const ContentSettingsPattern& secondary_pattern,
496 const ResourceIdentifier& resource_identifier,
497 const base::Value* value) {
498 DCHECK(IsContentSettingsTypeSyncable(content_type_));
500 // The incognito provider cannot write the settings to avoid echo effect:
501 // New preference -> PrefProvider -> Old preference ->
502 // -> Incognito PrefProvider -> New preference -> etc.
503 DCHECK(!is_incognito_);
505 if (*updating_old_preferences_)
506 return;
508 base::AutoReset<bool> auto_reset(updating_old_preferences_, true);
510 DictionaryPrefUpdate update(prefs_,
511 prefs::kContentSettingsPatternPairs);
512 base::DictionaryValue* pattern_pairs_settings = update.Get();
514 // Get settings dictionary for the given patterns.
515 std::string pattern_str(CreatePatternString(primary_pattern,
516 secondary_pattern));
517 base::DictionaryValue* settings_dictionary = NULL;
518 bool found = pattern_pairs_settings->GetDictionaryWithoutPathExpansion(
519 pattern_str, &settings_dictionary);
521 if (!found && value) {
522 settings_dictionary = new base::DictionaryValue;
523 pattern_pairs_settings->SetWithoutPathExpansion(
524 pattern_str, settings_dictionary);
527 if (settings_dictionary) {
528 if (content_type_ == CONTENT_SETTINGS_TYPE_PLUGINS &&
529 !resource_identifier.empty()) {
530 base::DictionaryValue* resource_dictionary = NULL;
531 found = settings_dictionary->GetDictionary(
532 kPerPluginPrefName, &resource_dictionary);
533 if (!found) {
534 if (value == NULL)
535 return; // Nothing to remove. Exit early.
536 resource_dictionary = new base::DictionaryValue;
537 settings_dictionary->Set(kPerPluginPrefName, resource_dictionary);
539 // Update resource dictionary.
540 if (value == NULL) {
541 resource_dictionary->RemoveWithoutPathExpansion(resource_identifier,
542 NULL);
543 if (resource_dictionary->empty()) {
544 settings_dictionary->RemoveWithoutPathExpansion(
545 kPerPluginPrefName, NULL);
547 } else {
548 resource_dictionary->SetWithoutPathExpansion(
549 resource_identifier, value->DeepCopy());
551 } else {
552 // Update settings dictionary.
553 std::string setting_path = GetTypeName(content_type_);
554 if (value == NULL) {
555 settings_dictionary->RemoveWithoutPathExpansion(setting_path,
556 NULL);
557 settings_dictionary->RemoveWithoutPathExpansion(kLastUsed, NULL);
558 } else {
559 settings_dictionary->SetWithoutPathExpansion(
560 setting_path, value->DeepCopy());
563 // Remove the settings dictionary if it is empty.
564 if (settings_dictionary->empty()) {
565 pattern_pairs_settings->RemoveWithoutPathExpansion(
566 pattern_str, NULL);
572 void ContentSettingsPref::ClearOldPreference() {
573 DCHECK(IsContentSettingsTypeSyncable(content_type_));
575 if (*updating_old_preferences_)
576 return;
578 std::vector<std::string> keys;
580 base::AutoReset<bool> auto_reset(updating_old_preferences_, true);
581 DictionaryPrefUpdate update(prefs_, prefs::kContentSettingsPatternPairs);
582 base::DictionaryValue* old_dictionary = update.Get();
584 for (base::DictionaryValue::Iterator it(*old_dictionary);
585 !it.IsAtEnd(); it.Advance()) {
586 keys.push_back(it.key());
589 for (const std::string& key : keys) {
590 base::DictionaryValue* exception;
591 bool is_dictionary =
592 old_dictionary->GetDictionaryWithoutPathExpansion(key, &exception);
593 DCHECK(is_dictionary);
595 exception->RemoveWithoutPathExpansion(GetTypeName(content_type_), NULL);
597 base::DictionaryValue* last_used;
598 if (exception->GetDictionaryWithoutPathExpansion(kLastUsed, &last_used)) {
599 last_used->RemoveWithoutPathExpansion(GetTypeName(content_type_), NULL);
601 if (last_used->empty())
602 exception->RemoveWithoutPathExpansion(kLastUsed, NULL);
605 if (content_type_ == CONTENT_SETTINGS_TYPE_PLUGINS)
606 exception->RemoveWithoutPathExpansion(kPerPluginPrefName, NULL);
608 if (exception->empty())
609 old_dictionary->RemoveWithoutPathExpansion(key, NULL);
614 // static
615 void ContentSettingsPref::CanonicalizeContentSettingsExceptions(
616 base::DictionaryValue* all_settings_dictionary) {
617 DCHECK(all_settings_dictionary);
619 std::vector<std::string> remove_items;
620 base::StringPairs move_items;
621 for (base::DictionaryValue::Iterator i(*all_settings_dictionary);
622 !i.IsAtEnd();
623 i.Advance()) {
624 const std::string& pattern_str(i.key());
625 std::pair<ContentSettingsPattern, ContentSettingsPattern> pattern_pair =
626 ParsePatternString(pattern_str);
627 if (!pattern_pair.first.IsValid() ||
628 !pattern_pair.second.IsValid()) {
629 LOG(ERROR) << "Invalid pattern strings: " << pattern_str;
630 continue;
633 const std::string canonicalized_pattern_str = CreatePatternString(
634 pattern_pair.first, pattern_pair.second);
636 if (canonicalized_pattern_str.empty() ||
637 canonicalized_pattern_str == pattern_str) {
638 continue;
641 // Clear old pattern if prefs already have canonicalized pattern.
642 const base::DictionaryValue* new_pattern_settings_dictionary = NULL;
643 if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
644 canonicalized_pattern_str, &new_pattern_settings_dictionary)) {
645 remove_items.push_back(pattern_str);
646 continue;
649 // Move old pattern to canonicalized pattern.
650 const base::DictionaryValue* old_pattern_settings_dictionary = NULL;
651 if (i.value().GetAsDictionary(&old_pattern_settings_dictionary)) {
652 move_items.push_back(
653 std::make_pair(pattern_str, canonicalized_pattern_str));
657 for (size_t i = 0; i < remove_items.size(); ++i) {
658 all_settings_dictionary->RemoveWithoutPathExpansion(remove_items[i], NULL);
661 for (size_t i = 0; i < move_items.size(); ++i) {
662 scoped_ptr<base::Value> pattern_settings_dictionary;
663 all_settings_dictionary->RemoveWithoutPathExpansion(
664 move_items[i].first, &pattern_settings_dictionary);
665 all_settings_dictionary->SetWithoutPathExpansion(
666 move_items[i].second, pattern_settings_dictionary.release());
670 void ContentSettingsPref::AssertLockNotHeld() const {
671 #if !defined(NDEBUG)
672 // |Lock::Acquire()| will assert if the lock is held by this thread.
673 lock_.Acquire();
674 lock_.Release();
675 #endif
678 } // namespace content_settings