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.
4 
5 #include "components/content_settings/core/browser/host_content_settings_map.h"
6 
7 #include <stddef.h>
8 
9 #include <algorithm>
10 #include <memory>
11 #include <utility>
12 
13 #include "base/command_line.h"
14 #include "base/containers/flat_map.h"
15 #include "base/metrics/histogram_functions.h"
16 #include "base/metrics/histogram_macros.h"
17 #include "base/stl_util.h"
18 #include "base/strings/string_util.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "base/threading/thread_task_runner_handle.h"
21 #include "base/time/clock.h"
22 #include "base/trace_event/trace_event.h"
23 #include "base/values.h"
24 #include "build/build_config.h"
25 #include "components/content_settings/core/browser/content_settings_default_provider.h"
26 #include "components/content_settings/core/browser/content_settings_details.h"
27 #include "components/content_settings/core/browser/content_settings_ephemeral_provider.h"
28 #include "components/content_settings/core/browser/content_settings_info.h"
29 #include "components/content_settings/core/browser/content_settings_observable_provider.h"
30 #include "components/content_settings/core/browser/content_settings_policy_provider.h"
31 #include "components/content_settings/core/browser/content_settings_pref_provider.h"
32 #include "components/content_settings/core/browser/content_settings_provider.h"
33 #include "components/content_settings/core/browser/content_settings_registry.h"
34 #include "components/content_settings/core/browser/content_settings_rule.h"
35 #include "components/content_settings/core/browser/content_settings_utils.h"
36 #include "components/content_settings/core/browser/user_modifiable_provider.h"
37 #include "components/content_settings/core/browser/website_settings_registry.h"
38 #include "components/content_settings/core/common/content_settings_pattern.h"
39 #include "components/content_settings/core/common/content_settings_types.h"
40 #include "components/content_settings/core/common/content_settings_utils.h"
41 #include "components/content_settings/core/common/pref_names.h"
42 #include "components/pref_registry/pref_registry_syncable.h"
43 #include "components/prefs/pref_service.h"
44 #include "net/base/net_errors.h"
45 #include "net/cookies/static_cookie_policy.h"
46 #include "url/gurl.h"
47 
48 using content_settings::WebsiteSettingsInfo;
49 using content_settings::ContentSettingsInfo;
50 
51 namespace {
52 
53 typedef std::vector<content_settings::Rule> Rules;
54 
55 typedef std::pair<std::string, std::string> StringPair;
56 
57 struct ProviderNamesSourceMapEntry {
58   const char* provider_name;
59   content_settings::SettingSource provider_source;
60 };
61 
62 const HostContentSettingsMap::ProviderType kFirstProvider =
63     HostContentSettingsMap::POLICY_PROVIDER;
64 const HostContentSettingsMap::ProviderType kFirstUserModifiableProvider =
65     HostContentSettingsMap::NOTIFICATION_ANDROID_PROVIDER;
66 
67 constexpr ProviderNamesSourceMapEntry kProviderNamesSourceMap[] = {
68     {"policy", content_settings::SETTING_SOURCE_POLICY},
69     {"supervised_user", content_settings::SETTING_SOURCE_SUPERVISED},
70     {"extension", content_settings::SETTING_SOURCE_EXTENSION},
71     {"installed_webapp_provider",
72       content_settings::SETTING_SOURCE_INSTALLED_WEBAPP},
73     {"notification_android", content_settings::SETTING_SOURCE_USER},
74     {"ephemeral", content_settings::SETTING_SOURCE_USER},
75     {"preference", content_settings::SETTING_SOURCE_USER},
76     {"default", content_settings::SETTING_SOURCE_USER},
77     {"tests", content_settings::SETTING_SOURCE_USER},
78     {"tests_other", content_settings::SETTING_SOURCE_USER},
79 };
80 
81 static_assert(
82     base::size(kProviderNamesSourceMap) ==
83         HostContentSettingsMap::NUM_PROVIDER_TYPES,
84     "kProviderNamesSourceMap should have NUM_PROVIDER_TYPES elements");
85 
86 // Ensure that kFirstUserModifiableProvider is actually the highest precedence
87 // user modifiable provider.
FirstUserModifiableProviderIsHighestPrecedence()88 constexpr bool FirstUserModifiableProviderIsHighestPrecedence() {
89   for (size_t i = 0; i < kFirstUserModifiableProvider; ++i) {
90     if (kProviderNamesSourceMap[i].provider_source ==
91         content_settings::SETTING_SOURCE_USER) {
92       return false;
93     }
94   }
95   return kProviderNamesSourceMap[kFirstUserModifiableProvider]
96              .provider_source == content_settings::SETTING_SOURCE_USER;
97 }
98 static_assert(FirstUserModifiableProviderIsHighestPrecedence(),
99               "kFirstUserModifiableProvider is not the highest precedence user "
100               "modifiable provider.");
101 
102 // Returns true if the |content_type| supports a resource identifier.
103 // Resource identifiers are supported (but not required) for plugins.
SupportsResourceIdentifier(ContentSettingsType content_type)104 bool SupportsResourceIdentifier(ContentSettingsType content_type) {
105   return content_type == ContentSettingsType::PLUGINS;
106 }
107 
SchemeCanBeWhitelisted(const std::string & scheme)108 bool SchemeCanBeWhitelisted(const std::string& scheme) {
109   return scheme == content_settings::kChromeDevToolsScheme ||
110          scheme == content_settings::kExtensionScheme ||
111          scheme == content_settings::kChromeUIScheme;
112 }
113 
114 // Handles inheritance of settings from the regular profile into the incognito
115 // profile.
ProcessIncognitoInheritanceBehavior(ContentSettingsType content_type,std::unique_ptr<base::Value> value)116 std::unique_ptr<base::Value> ProcessIncognitoInheritanceBehavior(
117     ContentSettingsType content_type,
118     std::unique_ptr<base::Value> value) {
119   // Website setting inheritance can be completely disallowed.
120   const WebsiteSettingsInfo* website_settings_info =
121       content_settings::WebsiteSettingsRegistry::GetInstance()->Get(
122           content_type);
123   if (website_settings_info &&
124       website_settings_info->incognito_behavior() ==
125           WebsiteSettingsInfo::DONT_INHERIT_IN_INCOGNITO) {
126     return nullptr;
127   }
128 
129   // Content setting inheritance can be for settings, that are more permissive
130   // than the initial value of a content setting.
131   const ContentSettingsInfo* content_settings_info =
132       content_settings::ContentSettingsRegistry::GetInstance()->Get(
133           content_type);
134   if (content_settings_info) {
135     ContentSettingsInfo::IncognitoBehavior behaviour =
136         content_settings_info->incognito_behavior();
137     switch (behaviour) {
138       case ContentSettingsInfo::INHERIT_IN_INCOGNITO:
139         return value;
140       case ContentSettingsInfo::INHERIT_IF_LESS_PERMISSIVE:
141         ContentSetting setting =
142             content_settings::ValueToContentSetting(value.get());
143         const base::Value* initial_value = content_settings_info
144             ->website_settings_info()->initial_default_value();
145         ContentSetting initial_setting =
146             content_settings::ValueToContentSetting(initial_value);
147         if (content_settings::IsMorePermissive(setting, initial_setting))
148           return content_settings::ContentSettingToValue(initial_setting);
149         return value;
150     }
151   }
152 
153   return value;
154 }
155 
GetPatternsFromScopingType(WebsiteSettingsInfo::ScopingType scoping_type,const GURL & primary_url,const GURL & secondary_url)156 content_settings::PatternPair GetPatternsFromScopingType(
157     WebsiteSettingsInfo::ScopingType scoping_type,
158     const GURL& primary_url,
159     const GURL& secondary_url) {
160   DCHECK(!primary_url.is_empty());
161   content_settings::PatternPair patterns;
162 
163   switch (scoping_type) {
164     case WebsiteSettingsInfo::COOKIES_SCOPE:
165       patterns.first = ContentSettingsPattern::FromURL(primary_url);
166       patterns.second = ContentSettingsPattern::Wildcard();
167       break;
168     case WebsiteSettingsInfo::SINGLE_ORIGIN_ONLY_SCOPE:
169     case WebsiteSettingsInfo::SINGLE_ORIGIN_WITH_EMBEDDED_EXCEPTIONS_SCOPE:
170       patterns.first = ContentSettingsPattern::FromURLNoWildcard(primary_url);
171       patterns.second = ContentSettingsPattern::Wildcard();
172       break;
173     case WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE:
174       DCHECK(!secondary_url.is_empty());
175       patterns.first = ContentSettingsPattern::FromURLNoWildcard(primary_url);
176       patterns.second =
177           ContentSettingsPattern::FromURLNoWildcard(secondary_url);
178       break;
179   }
180   return patterns;
181 }
182 
GetPatternsForContentSettingsType(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType type)183 content_settings::PatternPair GetPatternsForContentSettingsType(
184     const GURL& primary_url,
185     const GURL& secondary_url,
186     ContentSettingsType type) {
187   const WebsiteSettingsInfo* website_settings_info =
188       content_settings::WebsiteSettingsRegistry::GetInstance()->Get(type);
189   DCHECK(website_settings_info);
190   content_settings::PatternPair patterns = GetPatternsFromScopingType(
191       website_settings_info->scoping_type(), primary_url, secondary_url);
192   return patterns;
193 }
194 
195 // This enum is used to collect Flash permission data.
196 enum class FlashPermissions {
197   kFirstTime = 0,
198   kRepeated = 1,
199   kMaxValue = kRepeated,
200 };
201 
202 // Returns whether per-content setting exception information should be
203 // collected. All content settings for which this method returns true here be
204 // content settings, not website settings (i.e. their value should be a
205 // ContentSetting).
206 //
207 // This method should be kept in sync with histograms.xml, as every type here
208 // is an affected histogram under the "ContentSetting" suffix.
ShouldCollectFineGrainedExceptionHistograms(ContentSettingsType type)209 bool ShouldCollectFineGrainedExceptionHistograms(ContentSettingsType type) {
210   switch (type) {
211     case ContentSettingsType::COOKIES:
212     case ContentSettingsType::POPUPS:
213     case ContentSettingsType::ADS:
214       return true;
215     default:
216       return false;
217   }
218 }
219 
ContentSettingToString(ContentSetting setting)220 const char* ContentSettingToString(ContentSetting setting) {
221   switch (setting) {
222     case CONTENT_SETTING_ALLOW:
223       return "Allow";
224     case CONTENT_SETTING_BLOCK:
225       return "Block";
226     case CONTENT_SETTING_ASK:
227       return "Ask";
228     case CONTENT_SETTING_SESSION_ONLY:
229       return "SessionOnly";
230     case CONTENT_SETTING_DETECT_IMPORTANT_CONTENT:
231       return "DetectImportantContent";
232     case CONTENT_SETTING_DEFAULT:
233     case CONTENT_SETTING_NUM_SETTINGS:
234       NOTREACHED();
235       return nullptr;
236   }
237 }
238 
239 }  // namespace
240 
HostContentSettingsMap(PrefService * prefs,bool is_off_the_record,bool store_last_modified,bool migrate_requesting_and_top_level_origin_settings)241 HostContentSettingsMap::HostContentSettingsMap(
242     PrefService* prefs,
243     bool is_off_the_record,
244     bool store_last_modified,
245     bool migrate_requesting_and_top_level_origin_settings)
246     : RefcountedKeyedService(base::ThreadTaskRunnerHandle::Get()),
247 #ifndef NDEBUG
248       used_from_thread_id_(base::PlatformThread::CurrentId()),
249 #endif
250       prefs_(prefs),
251       is_off_the_record_(is_off_the_record),
252       store_last_modified_(store_last_modified) {
253   TRACE_EVENT0("startup", "HostContentSettingsMap::HostContentSettingsMap");
254 
255   auto policy_provider_ptr =
256       std::make_unique<content_settings::PolicyProvider>(prefs_);
257   auto* policy_provider = policy_provider_ptr.get();
258   content_settings_providers_[POLICY_PROVIDER] = std::move(policy_provider_ptr);
259   policy_provider->AddObserver(this);
260 
261   auto pref_provider_ptr = std::make_unique<content_settings::PrefProvider>(
262       prefs_, is_off_the_record_, store_last_modified_);
263   pref_provider_ = pref_provider_ptr.get();
264   content_settings_providers_[PREF_PROVIDER] = std::move(pref_provider_ptr);
265   user_modifiable_providers_.push_back(pref_provider_);
266   pref_provider_->AddObserver(this);
267 
268   auto ephemeral_provider_ptr =
269       std::make_unique<content_settings::EphemeralProvider>(
270           store_last_modified_);
271   auto* ephemeral_provider = ephemeral_provider_ptr.get();
272   content_settings_providers_[EPHEMERAL_PROVIDER] =
273       std::move(ephemeral_provider_ptr);
274   user_modifiable_providers_.push_back(ephemeral_provider);
275   ephemeral_provider->AddObserver(this);
276 
277   auto default_provider = std::make_unique<content_settings::DefaultProvider>(
278       prefs_, is_off_the_record_);
279   default_provider->AddObserver(this);
280   content_settings_providers_[DEFAULT_PROVIDER] = std::move(default_provider);
281 
282   InitializePluginsDataSettings();
283   if (migrate_requesting_and_top_level_origin_settings)
284     MigrateRequestingAndTopLevelOriginSettings();
285   RecordExceptionMetrics();
286 }
287 
288 // static
RegisterProfilePrefs(user_prefs::PrefRegistrySyncable * registry)289 void HostContentSettingsMap::RegisterProfilePrefs(
290     user_prefs::PrefRegistrySyncable* registry) {
291   // Ensure the content settings are all registered.
292   content_settings::ContentSettingsRegistry::GetInstance();
293 
294   registry->RegisterIntegerPref(prefs::kContentSettingsWindowLastTabIndex, 0);
295 
296   // Register the prefs for the content settings providers.
297   content_settings::DefaultProvider::RegisterProfilePrefs(registry);
298   content_settings::PrefProvider::RegisterProfilePrefs(registry);
299   content_settings::PolicyProvider::RegisterProfilePrefs(registry);
300 }
301 
RegisterUserModifiableProvider(ProviderType type,std::unique_ptr<content_settings::UserModifiableProvider> provider)302 void HostContentSettingsMap::RegisterUserModifiableProvider(
303     ProviderType type,
304     std::unique_ptr<content_settings::UserModifiableProvider> provider) {
305   user_modifiable_providers_.push_back(provider.get());
306   RegisterProvider(type, std::move(provider));
307 }
308 
RegisterProvider(ProviderType type,std::unique_ptr<content_settings::ObservableProvider> provider)309 void HostContentSettingsMap::RegisterProvider(
310     ProviderType type,
311     std::unique_ptr<content_settings::ObservableProvider> provider) {
312   DCHECK(!content_settings_providers_[type]);
313   provider->AddObserver(this);
314   content_settings_providers_[type] = std::move(provider);
315 
316 #ifndef NDEBUG
317   DCHECK_NE(used_from_thread_id_, base::kInvalidThreadId)
318       << "Used from multiple threads before initialization complete.";
319 #endif
320 
321   OnContentSettingChanged(ContentSettingsPattern(), ContentSettingsPattern(),
322                           ContentSettingsType::DEFAULT, std::string());
323 }
324 
GetDefaultContentSettingFromProvider(ContentSettingsType content_type,content_settings::ProviderInterface * provider) const325 ContentSetting HostContentSettingsMap::GetDefaultContentSettingFromProvider(
326     ContentSettingsType content_type,
327     content_settings::ProviderInterface* provider) const {
328   std::unique_ptr<content_settings::RuleIterator> rule_iterator(
329       provider->GetRuleIterator(content_type, std::string(), false));
330 
331   if (rule_iterator) {
332     ContentSettingsPattern wildcard = ContentSettingsPattern::Wildcard();
333     while (rule_iterator->HasNext()) {
334       content_settings::Rule rule = rule_iterator->Next();
335       if (rule.primary_pattern == wildcard &&
336           rule.secondary_pattern == wildcard) {
337         return content_settings::ValueToContentSetting(&rule.value);
338       }
339     }
340   }
341   return CONTENT_SETTING_DEFAULT;
342 }
343 
GetDefaultContentSettingInternal(ContentSettingsType content_type,ProviderType * provider_type) const344 ContentSetting HostContentSettingsMap::GetDefaultContentSettingInternal(
345     ContentSettingsType content_type,
346     ProviderType* provider_type) const {
347   DCHECK(provider_type);
348   UsedContentSettingsProviders();
349 
350   // Iterate through the list of providers and return the first non-NULL value
351   // that matches |primary_url| and |secondary_url|.
352   for (const auto& provider_pair : content_settings_providers_) {
353     if (provider_pair.first == PREF_PROVIDER)
354       continue;
355     ContentSetting default_setting = GetDefaultContentSettingFromProvider(
356         content_type, provider_pair.second.get());
357     if (is_off_the_record_) {
358       default_setting = content_settings::ValueToContentSetting(
359           ProcessIncognitoInheritanceBehavior(
360               content_type,
361               content_settings::ContentSettingToValue(default_setting))
362               .get());
363     }
364     if (default_setting != CONTENT_SETTING_DEFAULT) {
365       *provider_type = provider_pair.first;
366       return default_setting;
367     }
368   }
369 
370   return CONTENT_SETTING_DEFAULT;
371 }
372 
GetDefaultContentSetting(ContentSettingsType content_type,std::string * provider_id) const373 ContentSetting HostContentSettingsMap::GetDefaultContentSetting(
374     ContentSettingsType content_type,
375     std::string* provider_id) const {
376   ProviderType provider_type = NUM_PROVIDER_TYPES;
377   ContentSetting content_setting =
378       GetDefaultContentSettingInternal(content_type, &provider_type);
379   if (content_setting != CONTENT_SETTING_DEFAULT && provider_id)
380     *provider_id = kProviderNamesSourceMap[provider_type].provider_name;
381   return content_setting;
382 }
383 
GetContentSetting(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier) const384 ContentSetting HostContentSettingsMap::GetContentSetting(
385     const GURL& primary_url,
386     const GURL& secondary_url,
387     ContentSettingsType content_type,
388     const std::string& resource_identifier) const {
389   DCHECK(content_settings::ContentSettingsRegistry::GetInstance()->Get(
390       content_type));
391   std::unique_ptr<base::Value> value = GetWebsiteSetting(
392       primary_url, secondary_url, content_type, resource_identifier, nullptr);
393   return content_settings::ValueToContentSetting(value.get());
394 }
395 
GetUserModifiableContentSetting(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier) const396 ContentSetting HostContentSettingsMap::GetUserModifiableContentSetting(
397     const GURL& primary_url,
398     const GURL& secondary_url,
399     ContentSettingsType content_type,
400     const std::string& resource_identifier) const {
401   DCHECK(content_settings::ContentSettingsRegistry::GetInstance()->Get(
402       content_type));
403   std::unique_ptr<base::Value> value = GetWebsiteSettingInternal(
404       primary_url, secondary_url, content_type, resource_identifier,
405       kFirstUserModifiableProvider, nullptr);
406   return content_settings::ValueToContentSetting(value.get());
407 }
408 
GetSettingsForOneType(ContentSettingsType content_type,const std::string & resource_identifier,ContentSettingsForOneType * settings) const409 void HostContentSettingsMap::GetSettingsForOneType(
410     ContentSettingsType content_type,
411     const std::string& resource_identifier,
412     ContentSettingsForOneType* settings) const {
413   DCHECK(SupportsResourceIdentifier(content_type) ||
414          resource_identifier.empty());
415   DCHECK(settings);
416   UsedContentSettingsProviders();
417 
418   settings->clear();
419   for (const auto& provider_pair : content_settings_providers_) {
420     // For each provider, iterate first the incognito-specific rules, then the
421     // normal rules.
422     if (is_off_the_record_) {
423       AddSettingsForOneType(provider_pair.second.get(), provider_pair.first,
424                             content_type, resource_identifier, settings, true);
425     }
426     AddSettingsForOneType(provider_pair.second.get(), provider_pair.first,
427                           content_type, resource_identifier, settings, false);
428   }
429 }
430 
SetDefaultContentSetting(ContentSettingsType content_type,ContentSetting setting)431 void HostContentSettingsMap::SetDefaultContentSetting(
432     ContentSettingsType content_type,
433     ContentSetting setting) {
434   std::unique_ptr<base::Value> value;
435   // A value of CONTENT_SETTING_DEFAULT implies deleting the content setting.
436   if (setting != CONTENT_SETTING_DEFAULT) {
437     DCHECK(content_settings::ContentSettingsRegistry::GetInstance()
438                ->Get(content_type)
439                ->IsDefaultSettingValid(setting));
440     value.reset(new base::Value(setting));
441   }
442   SetWebsiteSettingCustomScope(ContentSettingsPattern::Wildcard(),
443                                ContentSettingsPattern::Wildcard(), content_type,
444                                std::string(), std::move(value));
445 }
446 
SetWebsiteSettingDefaultScope(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier,std::unique_ptr<base::Value> value)447 void HostContentSettingsMap::SetWebsiteSettingDefaultScope(
448     const GURL& primary_url,
449     const GURL& secondary_url,
450     ContentSettingsType content_type,
451     const std::string& resource_identifier,
452     std::unique_ptr<base::Value> value) {
453   content_settings::PatternPair patterns = GetPatternsForContentSettingsType(
454       primary_url, secondary_url, content_type);
455   ContentSettingsPattern primary_pattern = patterns.first;
456   ContentSettingsPattern secondary_pattern = patterns.second;
457   if (!primary_pattern.IsValid() || !secondary_pattern.IsValid())
458     return;
459 
460   SetWebsiteSettingCustomScope(primary_pattern, secondary_pattern, content_type,
461                                resource_identifier, std::move(value));
462 }
463 
SetWebsiteSettingCustomScope(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,const std::string & resource_identifier,std::unique_ptr<base::Value> value)464 void HostContentSettingsMap::SetWebsiteSettingCustomScope(
465     const ContentSettingsPattern& primary_pattern,
466     const ContentSettingsPattern& secondary_pattern,
467     ContentSettingsType content_type,
468     const std::string& resource_identifier,
469     std::unique_ptr<base::Value> value) {
470   DCHECK(primary_pattern == secondary_pattern ||
471          secondary_pattern == ContentSettingsPattern::Wildcard() ||
472          content_settings::WebsiteSettingsRegistry::GetInstance()
473              ->Get(content_type)
474              ->SupportsEmbeddedExceptions() ||
475          content_settings::WebsiteSettingsRegistry::GetInstance()
476                  ->Get(content_type)
477                  ->scoping_type() ==
478              WebsiteSettingsInfo::REQUESTING_ORIGIN_AND_TOP_LEVEL_ORIGIN_SCOPE);
479   DCHECK(SupportsResourceIdentifier(content_type) ||
480          resource_identifier.empty());
481   // TODO(crbug.com/731126): Verify that assumptions for notification content
482   // settings are met.
483   UsedContentSettingsProviders();
484 
485   for (const auto& provider_pair : content_settings_providers_) {
486     if (provider_pair.second->SetWebsiteSetting(
487             primary_pattern, secondary_pattern, content_type,
488             resource_identifier, std::move(value))) {
489       // If successful then ownership is passed to the provider.
490       return;
491     }
492   }
493   NOTREACHED();
494 }
495 
CanSetNarrowestContentSetting(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType type) const496 bool HostContentSettingsMap::CanSetNarrowestContentSetting(
497     const GURL& primary_url,
498     const GURL& secondary_url,
499     ContentSettingsType type) const {
500   content_settings::PatternPair patterns =
501       GetNarrowestPatterns(primary_url, secondary_url, type);
502   return patterns.first.IsValid() && patterns.second.IsValid();
503 }
504 
IsRestrictedToSecureOrigins(ContentSettingsType type) const505 bool HostContentSettingsMap::IsRestrictedToSecureOrigins(
506     ContentSettingsType type) const {
507   const ContentSettingsInfo* content_settings_info =
508       content_settings::ContentSettingsRegistry::GetInstance()->Get(type);
509   DCHECK(content_settings_info);
510 
511   return content_settings_info->origin_restriction() ==
512          ContentSettingsInfo::EXCEPTIONS_ON_SECURE_ORIGINS_ONLY;
513 }
514 
SetNarrowestContentSetting(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType type,ContentSetting setting)515 void HostContentSettingsMap::SetNarrowestContentSetting(
516     const GURL& primary_url,
517     const GURL& secondary_url,
518     ContentSettingsType type,
519     ContentSetting setting) {
520   content_settings::PatternPair patterns =
521       GetNarrowestPatterns(primary_url, secondary_url, type);
522 
523   if (!patterns.first.IsValid() || !patterns.second.IsValid())
524     return;
525 
526   SetContentSettingCustomScope(patterns.first, patterns.second, type,
527                                std::string(), setting);
528 }
529 
GetNarrowestPatterns(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType type) const530 content_settings::PatternPair HostContentSettingsMap::GetNarrowestPatterns (
531     const GURL& primary_url,
532     const GURL& secondary_url,
533     ContentSettingsType type) const {
534   // Permission settings are specified via rules. There exists always at least
535   // one rule for the default setting. Get the rule that currently defines
536   // the permission for the given permission |type|. Then test whether the
537   // existing rule is more specific than the rule we are about to create. If
538   // the existing rule is more specific, than change the existing rule instead
539   // of creating a new rule that would be hidden behind the existing rule.
540   content_settings::SettingInfo info;
541   std::unique_ptr<base::Value> v = GetWebsiteSettingInternal(
542       primary_url, secondary_url, type, std::string(), kFirstProvider, &info);
543   if (info.source != content_settings::SETTING_SOURCE_USER) {
544     // Return an invalid pattern if the current setting is not a user setting
545     // and thus can't be changed.
546     return content_settings::PatternPair();
547   }
548 
549   content_settings::PatternPair patterns = GetPatternsForContentSettingsType(
550       primary_url, secondary_url, type);
551 
552   ContentSettingsPattern::Relation r1 =
553       info.primary_pattern.Compare(patterns.first);
554   if (r1 == ContentSettingsPattern::PREDECESSOR) {
555     patterns.first = std::move(info.primary_pattern);
556   } else if (r1 == ContentSettingsPattern::IDENTITY) {
557     ContentSettingsPattern::Relation r2 =
558         info.secondary_pattern.Compare(patterns.second);
559     DCHECK(r2 != ContentSettingsPattern::DISJOINT_ORDER_POST &&
560            r2 != ContentSettingsPattern::DISJOINT_ORDER_PRE);
561     if (r2 == ContentSettingsPattern::PREDECESSOR)
562       patterns.second = std::move(info.secondary_pattern);
563   }
564 
565   return patterns;
566 }
567 
SetContentSettingCustomScope(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,const std::string & resource_identifier,ContentSetting setting)568 void HostContentSettingsMap::SetContentSettingCustomScope(
569     const ContentSettingsPattern& primary_pattern,
570     const ContentSettingsPattern& secondary_pattern,
571     ContentSettingsType content_type,
572     const std::string& resource_identifier,
573     ContentSetting setting) {
574   DCHECK(content_settings::ContentSettingsRegistry::GetInstance()->Get(
575       content_type));
576 
577   // Record stats on Flash permission grants with ephemeral storage.
578   if (content_type == ContentSettingsType::PLUGINS &&
579       setting == CONTENT_SETTING_ALLOW) {
580     GURL url(primary_pattern.ToString());
581     ContentSettingsPattern temp_patterns[2];
582     std::unique_ptr<base::Value> value(GetContentSettingValueAndPatterns(
583         content_settings_providers_[PREF_PROVIDER].get(), url, url,
584         ContentSettingsType::PLUGINS_DATA, resource_identifier,
585         is_off_the_record_, temp_patterns, temp_patterns + 1));
586 
587     UMA_HISTOGRAM_ENUMERATION(
588         "ContentSettings.EphemeralFlashPermission",
589         value ? FlashPermissions::kRepeated : FlashPermissions::kFirstTime);
590   }
591 
592   std::unique_ptr<base::Value> value;
593   // A value of CONTENT_SETTING_DEFAULT implies deleting the content setting.
594   if (setting != CONTENT_SETTING_DEFAULT) {
595     DCHECK(content_settings::ContentSettingsRegistry::GetInstance()
596                ->Get(content_type)
597                ->IsSettingValid(setting));
598     value.reset(new base::Value(setting));
599   }
600   SetWebsiteSettingCustomScope(primary_pattern, secondary_pattern, content_type,
601                                resource_identifier, std::move(value));
602 }
603 
SetContentSettingDefaultScope(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier,ContentSetting setting)604 void HostContentSettingsMap::SetContentSettingDefaultScope(
605     const GURL& primary_url,
606     const GURL& secondary_url,
607     ContentSettingsType content_type,
608     const std::string& resource_identifier,
609     ContentSetting setting) {
610   content_settings::PatternPair patterns = GetPatternsForContentSettingsType(
611       primary_url, secondary_url, content_type);
612 
613   ContentSettingsPattern primary_pattern = patterns.first;
614   ContentSettingsPattern secondary_pattern = patterns.second;
615   if (!primary_pattern.IsValid() || !secondary_pattern.IsValid())
616     return;
617 
618   SetContentSettingCustomScope(primary_pattern, secondary_pattern, content_type,
619                                resource_identifier, setting);
620 }
621 
GetWeakPtr()622 base::WeakPtr<HostContentSettingsMap> HostContentSettingsMap::GetWeakPtr() {
623   return weak_ptr_factory_.GetWeakPtr();
624 }
625 
SetClockForTesting(base::Clock * clock)626 void HostContentSettingsMap::SetClockForTesting(base::Clock* clock) {
627   for (auto* provider : user_modifiable_providers_)
628     provider->SetClockForTesting(clock);
629 }
630 
RecordExceptionMetrics()631 void HostContentSettingsMap::RecordExceptionMetrics() {
632   auto* content_setting_registry =
633       content_settings::ContentSettingsRegistry::GetInstance();
634   for (const content_settings::WebsiteSettingsInfo* info :
635        *content_settings::WebsiteSettingsRegistry::GetInstance()) {
636     ContentSettingsType content_type = info->type();
637     const std::string type_name = info->name();
638 
639     ContentSettingsForOneType settings;
640     GetSettingsForOneType(content_type, std::string(), &settings);
641     size_t num_exceptions = 0;
642     size_t num_third_party_cookie_allow_exceptions = 0;
643     base::flat_map<ContentSetting, size_t> num_exceptions_with_setting;
644     const content_settings::ContentSettingsInfo* content_info =
645         content_setting_registry->Get(content_type);
646     for (const ContentSettingPatternSource& setting_entry : settings) {
647       // Skip default settings.
648       if (setting_entry.primary_pattern == ContentSettingsPattern::Wildcard() &&
649           setting_entry.secondary_pattern ==
650               ContentSettingsPattern::Wildcard()) {
651         continue;
652       }
653 
654       ContentSettingsPattern::SchemeType scheme =
655           setting_entry.primary_pattern.GetScheme();
656       UMA_HISTOGRAM_ENUMERATION("ContentSettings.ExceptionScheme", scheme,
657                                 ContentSettingsPattern::SCHEME_MAX);
658 
659       if (scheme == ContentSettingsPattern::SCHEME_FILE) {
660         UMA_HISTOGRAM_BOOLEAN("ContentSettings.ExceptionSchemeFile.HasPath",
661                               setting_entry.primary_pattern.HasPath());
662         size_t num_values;
663         int histogram_value =
664             ContentSettingTypeToHistogramValue(content_type, &num_values);
665         if (setting_entry.primary_pattern.HasPath()) {
666           UMA_HISTOGRAM_EXACT_LINEAR(
667               "ContentSettings.ExceptionSchemeFile.Type.WithPath",
668               histogram_value, num_values);
669         } else {
670           UMA_HISTOGRAM_EXACT_LINEAR(
671               "ContentSettings.ExceptionSchemeFile.Type.WithoutPath",
672               histogram_value, num_values);
673         }
674       }
675 
676       if (setting_entry.source == "preference") {
677         // |content_info| will be non-nullptr iff |content_type| is a content
678         // setting rather than a website setting.
679         if (content_info)
680           ++num_exceptions_with_setting[setting_entry.GetContentSetting()];
681         ++num_exceptions;
682         if (content_type == ContentSettingsType::COOKIES &&
683             setting_entry.primary_pattern.MatchesAllHosts() &&
684             !setting_entry.secondary_pattern.MatchesAllHosts() &&
685             setting_entry.GetContentSetting() == CONTENT_SETTING_ALLOW) {
686           num_third_party_cookie_allow_exceptions++;
687         }
688       }
689     }
690 
691     std::string histogram_name =
692         "ContentSettings.Exceptions." + type_name;
693     base::UmaHistogramCustomCounts(histogram_name, num_exceptions, 1, 1000, 30);
694 
695     // For some ContentSettingTypes, collect exception histograms broken out by
696     // ContentSetting.
697     if (ShouldCollectFineGrainedExceptionHistograms(content_type)) {
698       DCHECK(content_info);
699       for (int setting = 0; setting < CONTENT_SETTING_NUM_SETTINGS; ++setting) {
700         ContentSetting content_setting = IntToContentSetting(setting);
701         if (!content_info->IsSettingValid(content_setting))
702           continue;
703         std::string histogram_with_suffix =
704             histogram_name + "." + ContentSettingToString(content_setting);
705         base::UmaHistogramCustomCounts(
706             histogram_with_suffix, num_exceptions_with_setting[content_setting],
707             1, 1000, 30);
708       }
709     }
710     if (content_type == ContentSettingsType::COOKIES) {
711       base::UmaHistogramCustomCounts(
712           "ContentSettings.Exceptions.cookies.AllowThirdParty",
713           num_third_party_cookie_allow_exceptions, 1, 1000, 30);
714     }
715   }
716 }
717 
AddObserver(content_settings::Observer * observer)718 void HostContentSettingsMap::AddObserver(content_settings::Observer* observer) {
719   observers_.AddObserver(observer);
720 }
721 
RemoveObserver(content_settings::Observer * observer)722 void HostContentSettingsMap::RemoveObserver(
723     content_settings::Observer* observer) {
724   observers_.RemoveObserver(observer);
725 }
726 
FlushLossyWebsiteSettings()727 void HostContentSettingsMap::FlushLossyWebsiteSettings() {
728   prefs_->SchedulePendingLossyWrites();
729 }
730 
ClearSettingsForOneType(ContentSettingsType content_type)731 void HostContentSettingsMap::ClearSettingsForOneType(
732     ContentSettingsType content_type) {
733   UsedContentSettingsProviders();
734   for (const auto& provider_pair : content_settings_providers_)
735     provider_pair.second->ClearAllContentSettingsRules(content_type);
736   FlushLossyWebsiteSettings();
737 }
738 
GetSettingLastModifiedDate(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type) const739 base::Time HostContentSettingsMap::GetSettingLastModifiedDate(
740     const ContentSettingsPattern& primary_pattern,
741     const ContentSettingsPattern& secondary_pattern,
742     ContentSettingsType content_type) const {
743   base::Time most_recent_time;
744   for (auto* provider : user_modifiable_providers_) {
745     base::Time time = provider->GetWebsiteSettingLastModified(
746         primary_pattern, secondary_pattern, content_type, std::string());
747     most_recent_time = std::max(time, most_recent_time);
748   }
749   return most_recent_time;
750 }
751 
ClearSettingsForOneTypeWithPredicate(ContentSettingsType content_type,base::Time begin_time,base::Time end_time,PatternSourcePredicate pattern_predicate)752 void HostContentSettingsMap::ClearSettingsForOneTypeWithPredicate(
753     ContentSettingsType content_type,
754     base::Time begin_time,
755     base::Time end_time,
756     PatternSourcePredicate pattern_predicate) {
757   if (pattern_predicate.is_null() && begin_time.is_null() &&
758       (end_time.is_null() || end_time.is_max())) {
759     ClearSettingsForOneType(content_type);
760     return;
761   }
762   UsedContentSettingsProviders();
763   ContentSettingsForOneType settings;
764   GetSettingsForOneType(content_type, std::string(), &settings);
765   for (const ContentSettingPatternSource& setting : settings) {
766     if (pattern_predicate.is_null() ||
767         pattern_predicate.Run(setting.primary_pattern,
768                               setting.secondary_pattern)) {
769       for (auto* provider : user_modifiable_providers_) {
770         base::Time last_modified = provider->GetWebsiteSettingLastModified(
771             setting.primary_pattern, setting.secondary_pattern, content_type,
772             std::string());
773         if (last_modified >= begin_time &&
774             (last_modified < end_time || end_time.is_null())) {
775           provider->SetWebsiteSetting(setting.primary_pattern,
776                                       setting.secondary_pattern, content_type,
777                                       std::string(), nullptr);
778         }
779       }
780     }
781   }
782 }
783 
OnContentSettingChanged(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,const std::string & resource_identifier)784 void HostContentSettingsMap::OnContentSettingChanged(
785     const ContentSettingsPattern& primary_pattern,
786     const ContentSettingsPattern& secondary_pattern,
787     ContentSettingsType content_type,
788     const std::string& resource_identifier) {
789   for (content_settings::Observer& observer : observers_) {
790     observer.OnContentSettingChanged(primary_pattern, secondary_pattern,
791                                      content_type, resource_identifier);
792   }
793 }
794 
~HostContentSettingsMap()795 HostContentSettingsMap::~HostContentSettingsMap() {
796   DCHECK(thread_checker_.CalledOnValidThread());
797   DCHECK(!prefs_);
798 }
799 
ShutdownOnUIThread()800 void HostContentSettingsMap::ShutdownOnUIThread() {
801   DCHECK(thread_checker_.CalledOnValidThread());
802   DCHECK(prefs_);
803   prefs_ = nullptr;
804   for (const auto& provider_pair : content_settings_providers_)
805     provider_pair.second->ShutdownOnUIThread();
806 }
807 
AddSettingsForOneType(const content_settings::ProviderInterface * provider,ProviderType provider_type,ContentSettingsType content_type,const std::string & resource_identifier,ContentSettingsForOneType * settings,bool incognito) const808 void HostContentSettingsMap::AddSettingsForOneType(
809     const content_settings::ProviderInterface* provider,
810     ProviderType provider_type,
811     ContentSettingsType content_type,
812     const std::string& resource_identifier,
813     ContentSettingsForOneType* settings,
814     bool incognito) const {
815   std::unique_ptr<content_settings::RuleIterator> rule_iterator(
816       provider->GetRuleIterator(content_type, resource_identifier, incognito));
817   if (!rule_iterator)
818     return;
819 
820   while (rule_iterator->HasNext()) {
821     content_settings::Rule rule = rule_iterator->Next();
822     base::Value value = std::move(rule.value);
823 
824     // Normal rules applied to incognito profiles are subject to inheritance
825     // settings.
826     if (!incognito && is_off_the_record_) {
827       std::unique_ptr<base::Value> inherit_value =
828           ProcessIncognitoInheritanceBehavior(
829               content_type, base::Value::ToUniquePtrValue(std::move(value)));
830       if (inherit_value)
831         value = std::move(*inherit_value);
832       else
833         continue;
834     }
835     settings->emplace_back(
836         rule.primary_pattern, rule.secondary_pattern, std::move(value),
837         kProviderNamesSourceMap[provider_type].provider_name, incognito);
838   }
839 }
840 
UsedContentSettingsProviders() const841 void HostContentSettingsMap::UsedContentSettingsProviders() const {
842 #ifndef NDEBUG
843   if (used_from_thread_id_ == base::kInvalidThreadId)
844     return;
845 
846   if (base::PlatformThread::CurrentId() != used_from_thread_id_)
847     used_from_thread_id_ = base::kInvalidThreadId;
848 #endif
849 }
850 
GetWebsiteSetting(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier,content_settings::SettingInfo * info) const851 std::unique_ptr<base::Value> HostContentSettingsMap::GetWebsiteSetting(
852     const GURL& primary_url,
853     const GURL& secondary_url,
854     ContentSettingsType content_type,
855     const std::string& resource_identifier,
856     content_settings::SettingInfo* info) const {
857   DCHECK(SupportsResourceIdentifier(content_type) ||
858          resource_identifier.empty());
859 
860   // Check if the requested setting is whitelisted.
861   // TODO(raymes): Move this into GetContentSetting. This has nothing to do with
862   // website settings
863   const content_settings::ContentSettingsInfo* content_settings_info =
864       content_settings::ContentSettingsRegistry::GetInstance()->Get(
865           content_type);
866   if (content_settings_info) {
867     for (const std::string& scheme :
868          content_settings_info->whitelisted_schemes()) {
869       DCHECK(SchemeCanBeWhitelisted(scheme));
870 
871       if (primary_url.SchemeIs(scheme)) {
872         if (info) {
873           info->source = content_settings::SETTING_SOURCE_WHITELIST;
874           info->primary_pattern = ContentSettingsPattern::Wildcard();
875           info->secondary_pattern = ContentSettingsPattern::Wildcard();
876         }
877         return std::unique_ptr<base::Value>(
878             new base::Value(CONTENT_SETTING_ALLOW));
879       }
880     }
881   }
882 
883   // Check if the requested setting is in the force allowed list.
884   if (content_settings_info) {
885     url::Origin origin = url::Origin::Create(primary_url);
886     if (content_settings_info->force_allowed_origins().contains(origin)) {
887       DCHECK(content_settings::OriginCanBeForceAllowed(origin));
888       if (info) {
889         info->source = content_settings::SETTING_SOURCE_WHITELIST;
890         info->primary_pattern =
891             ContentSettingsPattern::FromURLNoWildcard(origin.GetURL());
892         info->secondary_pattern = ContentSettingsPattern::Wildcard();
893       }
894       return std::make_unique<base::Value>(CONTENT_SETTING_ALLOW);
895     }
896   }
897 
898   return GetWebsiteSettingInternal(primary_url, secondary_url, content_type,
899                                    resource_identifier, kFirstProvider, info);
900 }
901 
902 // static
903 HostContentSettingsMap::ProviderType
GetProviderTypeFromSource(const std::string & source)904 HostContentSettingsMap::GetProviderTypeFromSource(const std::string& source) {
905   for (size_t i = 0; i < base::size(kProviderNamesSourceMap); ++i) {
906     if (source == kProviderNamesSourceMap[i].provider_name)
907       return static_cast<ProviderType>(i);
908   }
909 
910   NOTREACHED();
911   return DEFAULT_PROVIDER;
912 }
913 
914 // static
915 content_settings::SettingSource
GetSettingSourceFromProviderName(const std::string & provider_name)916 HostContentSettingsMap::GetSettingSourceFromProviderName(
917     const std::string& provider_name) {
918   for (const auto& provider_name_source : kProviderNamesSourceMap) {
919     if (provider_name == provider_name_source.provider_name)
920       return provider_name_source.provider_source;
921   }
922   NOTREACHED();
923   return content_settings::SETTING_SOURCE_NONE;
924 }
925 
GetWebsiteSettingInternal(const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier,ProviderType first_provider_to_search,content_settings::SettingInfo * info) const926 std::unique_ptr<base::Value> HostContentSettingsMap::GetWebsiteSettingInternal(
927     const GURL& primary_url,
928     const GURL& secondary_url,
929     ContentSettingsType content_type,
930     const std::string& resource_identifier,
931     ProviderType first_provider_to_search,
932     content_settings::SettingInfo* info) const {
933   UsedContentSettingsProviders();
934   ContentSettingsPattern* primary_pattern = nullptr;
935   ContentSettingsPattern* secondary_pattern = nullptr;
936   if (info) {
937     primary_pattern = &info->primary_pattern;
938     secondary_pattern = &info->secondary_pattern;
939   }
940 
941   // The list of |content_settings_providers_| is ordered according to their
942   // precedence.
943   auto it = content_settings_providers_.lower_bound(first_provider_to_search);
944   for (; it != content_settings_providers_.end(); ++it) {
945     std::unique_ptr<base::Value> value = GetContentSettingValueAndPatterns(
946         it->second.get(), primary_url, secondary_url, content_type,
947         resource_identifier, is_off_the_record_, primary_pattern,
948         secondary_pattern);
949     if (value) {
950       if (info)
951         info->source = kProviderNamesSourceMap[it->first].provider_source;
952       return value;
953     }
954   }
955 
956   if (info) {
957     info->source = content_settings::SETTING_SOURCE_NONE;
958     info->primary_pattern = ContentSettingsPattern();
959     info->secondary_pattern = ContentSettingsPattern();
960   }
961   return std::unique_ptr<base::Value>();
962 }
963 
964 // static
965 std::unique_ptr<base::Value>
GetContentSettingValueAndPatterns(const content_settings::ProviderInterface * provider,const GURL & primary_url,const GURL & secondary_url,ContentSettingsType content_type,const std::string & resource_identifier,bool include_incognito,ContentSettingsPattern * primary_pattern,ContentSettingsPattern * secondary_pattern)966 HostContentSettingsMap::GetContentSettingValueAndPatterns(
967     const content_settings::ProviderInterface* provider,
968     const GURL& primary_url,
969     const GURL& secondary_url,
970     ContentSettingsType content_type,
971     const std::string& resource_identifier,
972     bool include_incognito,
973     ContentSettingsPattern* primary_pattern,
974     ContentSettingsPattern* secondary_pattern) {
975   if (include_incognito) {
976     // Check incognito-only specific settings. It's essential that the
977     // |RuleIterator| gets out of scope before we get a rule iterator for the
978     // normal mode.
979     std::unique_ptr<content_settings::RuleIterator> incognito_rule_iterator(
980         provider->GetRuleIterator(content_type, resource_identifier,
981                                   true /* incognito */));
982     std::unique_ptr<base::Value> value = GetContentSettingValueAndPatterns(
983         incognito_rule_iterator.get(), primary_url, secondary_url,
984         primary_pattern, secondary_pattern);
985     if (value)
986       return value;
987   }
988   // No settings from the incognito; use the normal mode.
989   std::unique_ptr<content_settings::RuleIterator> rule_iterator(
990       provider->GetRuleIterator(content_type, resource_identifier,
991                                 false /* incognito */));
992   std::unique_ptr<base::Value> value = GetContentSettingValueAndPatterns(
993       rule_iterator.get(), primary_url, secondary_url, primary_pattern,
994       secondary_pattern);
995   if (value && include_incognito)
996     value = ProcessIncognitoInheritanceBehavior(content_type, std::move(value));
997   return value;
998 }
999 
1000 // static
1001 std::unique_ptr<base::Value>
GetContentSettingValueAndPatterns(content_settings::RuleIterator * rule_iterator,const GURL & primary_url,const GURL & secondary_url,ContentSettingsPattern * primary_pattern,ContentSettingsPattern * secondary_pattern)1002 HostContentSettingsMap::GetContentSettingValueAndPatterns(
1003     content_settings::RuleIterator* rule_iterator,
1004     const GURL& primary_url,
1005     const GURL& secondary_url,
1006     ContentSettingsPattern* primary_pattern,
1007     ContentSettingsPattern* secondary_pattern) {
1008   if (rule_iterator) {
1009     while (rule_iterator->HasNext()) {
1010       const content_settings::Rule& rule = rule_iterator->Next();
1011       if (rule.primary_pattern.Matches(primary_url) &&
1012           rule.secondary_pattern.Matches(secondary_url)) {
1013         if (primary_pattern)
1014           *primary_pattern = rule.primary_pattern;
1015         if (secondary_pattern)
1016           *secondary_pattern = rule.secondary_pattern;
1017         return rule.value.CreateDeepCopy();
1018       }
1019     }
1020   }
1021   return std::unique_ptr<base::Value>();
1022 }
1023 
InitializePluginsDataSettings()1024 void HostContentSettingsMap::InitializePluginsDataSettings() {
1025   if (!content_settings::WebsiteSettingsRegistry::GetInstance()->Get(
1026           ContentSettingsType::PLUGINS_DATA)) {
1027     return;
1028   }
1029   ContentSettingsForOneType host_settings;
1030   GetSettingsForOneType(ContentSettingsType::PLUGINS_DATA, std::string(),
1031                         &host_settings);
1032   if (host_settings.empty()) {
1033     GetSettingsForOneType(ContentSettingsType::PLUGINS, std::string(),
1034                           &host_settings);
1035     for (ContentSettingPatternSource pattern : host_settings) {
1036       if (pattern.source != "preference")
1037         continue;
1038       const GURL primary(pattern.primary_pattern.ToString());
1039       if (!primary.is_valid())
1040         continue;
1041       DCHECK_EQ(ContentSettingsPattern::Relation::IDENTITY,
1042                 ContentSettingsPattern::Wildcard().Compare(
1043                     pattern.secondary_pattern));
1044       auto dict = std::make_unique<base::DictionaryValue>();
1045       constexpr char kFlagKey[] = "flashPreviouslyChanged";
1046       dict->SetKey(kFlagKey, base::Value(true));
1047       SetWebsiteSettingDefaultScope(primary, primary,
1048                                     ContentSettingsType::PLUGINS_DATA,
1049                                     std::string(), std::move(dict));
1050     }
1051   }
1052 }
1053 
MigrateRequestingAndTopLevelOriginSettings()1054 void HostContentSettingsMap::MigrateRequestingAndTopLevelOriginSettings() {
1055   content_settings::ContentSettingsRegistry* registry =
1056       content_settings::ContentSettingsRegistry::GetInstance();
1057   for (const content_settings::ContentSettingsInfo* info : *registry) {
1058     // Only 3 types should be migrated.
1059     ContentSettingsType type = info->website_settings_info()->type();
1060     if (type != ContentSettingsType::GEOLOCATION &&
1061         type != ContentSettingsType::PROTECTED_MEDIA_IDENTIFIER &&
1062         type != ContentSettingsType::MIDI_SYSEX) {
1063       continue;
1064     }
1065 
1066     ContentSettingsForOneType host_settings;
1067     GetSettingsForOneType(type, std::string(), &host_settings);
1068     for (ContentSettingPatternSource pattern : host_settings) {
1069       if (pattern.source != "preference")
1070         continue;
1071 
1072       // Users were never allowed to add user-specified patterns for these types
1073       // so we can assume they are all origin scoped.
1074       DCHECK(GURL(pattern.primary_pattern.ToString()).is_valid());
1075       DCHECK(GURL(pattern.secondary_pattern.ToString()).is_valid());
1076 
1077       if (pattern.secondary_pattern.IsValid() &&
1078           pattern.secondary_pattern != pattern.primary_pattern &&
1079           pattern.secondary_pattern != ContentSettingsPattern::Wildcard()) {
1080         SetContentSettingCustomScope(pattern.primary_pattern,
1081                                      pattern.secondary_pattern, type,
1082                                      std::string(), CONTENT_SETTING_DEFAULT);
1083         // Also clear the setting for the top level origin so that the user
1084         // receives another prompt. This is necessary in case they have allowed
1085         // the top level origin but blocked an embedded origin in which case
1086         // they should have another opportunity to block a request from an
1087         // embedded origin.
1088         SetContentSettingCustomScope(pattern.secondary_pattern,
1089                                      pattern.secondary_pattern, type,
1090                                      std::string(), CONTENT_SETTING_DEFAULT);
1091         SetContentSettingCustomScope(pattern.secondary_pattern,
1092                                      ContentSettingsPattern::Wildcard(), type,
1093                                      std::string(), CONTENT_SETTING_DEFAULT);
1094       }
1095     }
1096   }
1097 }
1098