1 // Copyright 2018 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/content_settings_ephemeral_provider.h"
6
7 #include "base/stl_util.h"
8 #include "base/time/default_clock.h"
9 #include "components/content_settings/core/browser/content_settings_registry.h"
10 #include "components/content_settings/core/browser/website_settings_info.h"
11 #include "components/content_settings/core/browser/website_settings_registry.h"
12 #include "components/content_settings/core/common/content_settings.h"
13 #include "components/content_settings/core/common/content_settings_pattern.h"
14
15 namespace content_settings {
16
17 // ////////////////////////////////////////////////////////////////////////////
18 // EphemeralProvider:
19 //
20
EphemeralProvider(bool store_last_modified)21 EphemeralProvider::EphemeralProvider(bool store_last_modified)
22 : store_last_modified_(store_last_modified),
23 clock_(base::DefaultClock::GetInstance()) {
24 ContentSettingsRegistry* content_settings =
25 ContentSettingsRegistry::GetInstance();
26 WebsiteSettingsRegistry* website_settings =
27 WebsiteSettingsRegistry::GetInstance();
28 for (const WebsiteSettingsInfo* info : *website_settings) {
29 const ContentSettingsInfo* content_type_info =
30 content_settings->Get(info->type());
31 // If this is an ephemeral content setting, handle it in this class.
32 if (content_type_info && content_type_info->storage_behavior() ==
33 ContentSettingsInfo::EPHEMERAL) {
34 supported_types_.insert(info->type());
35 }
36 }
37 }
38
~EphemeralProvider()39 EphemeralProvider::~EphemeralProvider() {}
40
GetRuleIterator(ContentSettingsType content_type,const ResourceIdentifier & resource_identifier,bool incognito) const41 std::unique_ptr<RuleIterator> EphemeralProvider::GetRuleIterator(
42 ContentSettingsType content_type,
43 const ResourceIdentifier& resource_identifier,
44 bool incognito) const {
45 return content_settings_rules_.GetRuleIterator(content_type,
46 resource_identifier, nullptr);
47 }
48
SetWebsiteSetting(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,const ResourceIdentifier & resource_identifier,std::unique_ptr<base::Value> && in_value)49 bool EphemeralProvider::SetWebsiteSetting(
50 const ContentSettingsPattern& primary_pattern,
51 const ContentSettingsPattern& secondary_pattern,
52 ContentSettingsType content_type,
53 const ResourceIdentifier& resource_identifier,
54 std::unique_ptr<base::Value>&& in_value) {
55 DCHECK(CalledOnValidThread());
56
57 if (!base::Contains(supported_types_, content_type))
58 return false;
59
60 // Default settings are set using a wildcard pattern for both
61 // |primary_pattern| and |secondary_pattern|. Don't store default settings in
62 // the EphemeralProvider. The EphemeralProvider handles settings for
63 // specific sites/origins defined by the |primary_pattern| and the
64 // |secondary_pattern|. Default settings are handled by the DefaultProvider.
65 if (primary_pattern == ContentSettingsPattern::Wildcard() &&
66 secondary_pattern == ContentSettingsPattern::Wildcard() &&
67 resource_identifier.empty()) {
68 return false;
69 }
70
71 std::unique_ptr<base::Value> value(std::move(in_value));
72 if (value) {
73 content_settings_rules_.SetValue(
74 primary_pattern, secondary_pattern, content_type, resource_identifier,
75 store_last_modified_ ? clock_->Now() : base::Time(), std::move(*value));
76 NotifyObservers(primary_pattern, secondary_pattern, content_type,
77 resource_identifier);
78 } else {
79 // If the value exists, delete it.
80 if (content_settings_rules_.GetLastModified(
81 primary_pattern, secondary_pattern, content_type,
82 resource_identifier) != base::Time()) {
83 content_settings_rules_.DeleteValue(primary_pattern, secondary_pattern,
84 content_type, resource_identifier);
85 NotifyObservers(primary_pattern, secondary_pattern, content_type,
86 resource_identifier);
87 }
88 }
89 return true;
90 }
91
GetWebsiteSettingLastModified(const ContentSettingsPattern & primary_pattern,const ContentSettingsPattern & secondary_pattern,ContentSettingsType content_type,const ResourceIdentifier & resource_identifier)92 base::Time EphemeralProvider::GetWebsiteSettingLastModified(
93 const ContentSettingsPattern& primary_pattern,
94 const ContentSettingsPattern& secondary_pattern,
95 ContentSettingsType content_type,
96 const ResourceIdentifier& resource_identifier) {
97 DCHECK(CalledOnValidThread());
98
99 return content_settings_rules_.GetLastModified(
100 primary_pattern, secondary_pattern, content_type, resource_identifier);
101 }
102
ClearAllContentSettingsRules(ContentSettingsType content_type)103 void EphemeralProvider::ClearAllContentSettingsRules(
104 ContentSettingsType content_type) {
105 DCHECK(CalledOnValidThread());
106
107 // Get all resource identifiers for this |content_type|.
108 std::set<ResourceIdentifier> resource_identifiers;
109 for (OriginIdentifierValueMap::EntryMap::const_iterator entry =
110 content_settings_rules_.begin();
111 entry != content_settings_rules_.end(); entry++) {
112 if (entry->first.content_type == content_type)
113 resource_identifiers.insert(entry->first.resource_identifier);
114 }
115
116 for (const ResourceIdentifier& resource_identifier : resource_identifiers)
117 content_settings_rules_.DeleteValues(content_type, resource_identifier);
118
119 if (!resource_identifiers.empty()) {
120 NotifyObservers(ContentSettingsPattern(), ContentSettingsPattern(),
121 content_type, ResourceIdentifier());
122 }
123 }
124
ShutdownOnUIThread()125 void EphemeralProvider::ShutdownOnUIThread() {
126 DCHECK(CalledOnValidThread());
127 RemoveAllObservers();
128 }
129
SetClockForTesting(base::Clock * clock)130 void EphemeralProvider::SetClockForTesting(base::Clock* clock) {
131 clock_ = clock;
132 }
133
134 } // namespace content_settings
135