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

Side by Side Diff: chrome/browser/permissions/permission_decision_auto_blocker.cc

Issue 2184823007: Add a feature which, when enabled, blocks permissions after X prompt dismissals. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix unit test Created 4 years, 4 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 2016 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/permissions/permission_decision_auto_blocker.h"
6
7 #include <memory>
8
9 #include "base/feature_list.h"
10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
15 #include "chrome/browser/permissions/permission_uma_util.h"
16 #include "chrome/browser/permissions/permission_util.h"
17 #include "chrome/common/chrome_features.h"
18 #include "components/content_settings/core/browser/host_content_settings_map.h"
19 #include "components/variations/variations_associated_data.h"
20 #include "content/public/browser/permission_type.h"
21 #include "url/gurl.h"
22
23 namespace {
24
25 // The default number of times that users may explicitly dismiss a permission
26 // prompt from an origin before it is automatically blocked.
27 const int kPromptDismissalsBeforeBlock = 3;
28
29 std::unique_ptr<base::DictionaryValue> GetOriginDict(
30 HostContentSettingsMap* settings,
31 const GURL& origin_url) {
32 std::unique_ptr<base::DictionaryValue> dict =
33 base::DictionaryValue::From(settings->GetWebsiteSetting(
34 origin_url, origin_url,
35 CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT, std::string(),
36 nullptr));
37 if (!dict)
38 return base::WrapUnique(new base::DictionaryValue());
39
40 return dict;
41 }
42
43 base::DictionaryValue* GetOrCreatePermissionDict(
44 base::DictionaryValue* origin_dict,
45 const std::string& permission) {
46 base::DictionaryValue* permission_dict = nullptr;
47 if (!origin_dict->GetDictionaryWithoutPathExpansion(permission,
48 &permission_dict)) {
49 permission_dict = new base::DictionaryValue();
50 origin_dict->SetWithoutPathExpansion(permission,
51 base::WrapUnique(permission_dict));
52 }
53
54 return permission_dict;
55 }
56
57 } // namespace
58
59 // static
60 const char PermissionDecisionAutoBlocker::kPromptDismissCountKey[] =
61 "dismiss_count";
62
63 // static
64 const char PermissionDecisionAutoBlocker::kPromptIgnoreCountKey[] =
65 "ignore_count";
66
67 // static
68 void PermissionDecisionAutoBlocker::RemoveCountsByUrl(
69 Profile* profile,
70 base::Callback<bool(const GURL& url)> filter) {
71 HostContentSettingsMap* map =
72 HostContentSettingsMapFactory::GetForProfile(profile);
73
74 std::unique_ptr<ContentSettingsForOneType> settings(
75 new ContentSettingsForOneType);
76 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
77 std::string(), settings.get());
78
79 for (const auto& site : *settings) {
80 GURL origin(site.primary_pattern.ToString());
81
82 if (origin.is_valid() && filter.Run(origin)) {
83 map->SetWebsiteSettingDefaultScope(
84 origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
85 std::string(), nullptr);
86 }
87 }
88 }
89
90 PermissionDecisionAutoBlocker::PermissionDecisionAutoBlocker(Profile* profile)
91 : profile_(profile),
92 prompt_dismissals_before_block_(kPromptDismissalsBeforeBlock) {
93 UpdateFromVariations();
94 }
95
96 int PermissionDecisionAutoBlocker::RecordIgnore(
97 const GURL& url,
98 content::PermissionType permission) {
99 int current_ignore_count =
100 RecordAction(url, permission, kPromptIgnoreCountKey);
kcarattini 2016/08/08 06:14:31 Can you rename RecordAction to make it more clear
dominickn 2016/08/08 06:26:08 Done.
101
102 // |current_ignore_count| is always (count before this ignore + 1)
kcarattini 2016/08/08 06:14:31 I find it confusing that this and the previous Rec
dominickn 2016/08/08 06:26:08 Done.
103 PermissionUmaUtil::PermissionPromptIgnoreCount(permission,
104 current_ignore_count - 1);
105
106 return current_ignore_count;
107 }
108
109 bool PermissionDecisionAutoBlocker::ShouldChangeDismissalToBlock(
110 const GURL& url,
111 content::PermissionType permission) {
112 int current_dismissal_count =
113 RecordAction(url, permission, kPromptDismissCountKey);
114
115 // |current_dismissal_count| is always (count before this dismissal + 1)
116 PermissionUmaUtil::PermissionPromptDismissCount(permission,
117 current_dismissal_count - 1);
118
119 if (!base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften))
120 return false;
121
122 return current_dismissal_count >= prompt_dismissals_before_block_;
123 }
124
125 int PermissionDecisionAutoBlocker::GetActionCountForTest(
126 const GURL& url,
127 content::PermissionType permission,
128 const char* key) {
129 HostContentSettingsMap* map =
130 HostContentSettingsMapFactory::GetForProfile(profile_);
131 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
132
133 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
134 dict.get(), PermissionUtil::GetPermissionString(permission));
135
136 int current_count = 0;
137 permission_dict->GetInteger(key, &current_count);
138 return current_count;
139 }
140
141 int PermissionDecisionAutoBlocker::RecordAction(
142 const GURL& url,
143 content::PermissionType permission,
144 const char* key) {
145 HostContentSettingsMap* map =
146 HostContentSettingsMapFactory::GetForProfile(profile_);
147 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
148
149 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
150 dict.get(), PermissionUtil::GetPermissionString(permission));
151
152 int current_count = 0;
153 permission_dict->GetInteger(key, &current_count);
154 permission_dict->SetInteger(key, ++current_count);
155
156 map->SetWebsiteSettingDefaultScope(
157 url, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
158 std::string(), std::move(dict));
159
160 return current_count;
161 }
162
163 void PermissionDecisionAutoBlocker::UpdateFromVariations() {
164 int prompt_dismissals = -1;
165 std::string value = variations::GetVariationParamValueByFeature(
166 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey);
167
168 // If converting the value fails, stick with the default value.
169 if (base::StringToInt(value, &prompt_dismissals) && prompt_dismissals > 0)
170 prompt_dismissals_before_block_ = prompt_dismissals;
171 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698