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

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: Address comments 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 const char PermissionDecisionAutoBlocker::kPromptDismissCountKey[] =
raymes 2016/08/06 00:50:21 nit: // static
dominickn 2016/08/08 02:18:28 Done.
60 "dismiss_count";
61
62 void PermissionDecisionAutoBlocker::RemoveCountsByUrl(
63 Profile* profile,
64 base::Callback<bool(const GURL& url)> filter) {
65 HostContentSettingsMap* map =
66 HostContentSettingsMapFactory::GetForProfile(profile);
67
68 std::unique_ptr<ContentSettingsForOneType> settings(
69 new ContentSettingsForOneType);
70 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
71 std::string(), settings.get());
72
73 for (const auto& site : *settings) {
74 GURL origin(site.primary_pattern.ToString());
75
76 if (origin.is_valid() && filter.Run(origin)) {
77 map->SetWebsiteSettingDefaultScope(
78 origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
79 std::string(), nullptr);
80 }
81 }
82 }
83
84 PermissionDecisionAutoBlocker::PermissionDecisionAutoBlocker()
85 : prompt_dismissals_before_block_(kPromptDismissalsBeforeBlock) {
86 UpdateFromVariations();
87 }
88
89 bool PermissionDecisionAutoBlocker::ShouldChangeDismissalToBlock(
90 Profile* profile,
91 const GURL& url,
92 content::PermissionType permission) {
93 int current_dismissal_count = RecordDismissalCount(profile, url, permission);
94
95 // |current_dismissal_count| is always (count before this dismissal + 1)
96 PermissionUmaUtil::PermissionPromptDismissCount(permission,
97 current_dismissal_count - 1);
98
99 if (!base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften))
100 return false;
101
102 return current_dismissal_count >= prompt_dismissals_before_block_;
103 }
104
105 int PermissionDecisionAutoBlocker::GetDismissalCount(
106 Profile* profile,
107 const GURL& url,
108 content::PermissionType permission) {
109 HostContentSettingsMap* map =
110 HostContentSettingsMapFactory::GetForProfile(profile);
111 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
112
113 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
114 dict.get(), PermissionUtil::GetPermissionString(permission));
115
116 int current_count = 0;
117 permission_dict->GetInteger(kPromptDismissCountKey, &current_count);
118 return current_count;
119 }
120
121 int PermissionDecisionAutoBlocker::RecordDismissalCount(
122 Profile* profile,
123 const GURL& url,
124 content::PermissionType permission) {
125 HostContentSettingsMap* map =
126 HostContentSettingsMapFactory::GetForProfile(profile);
127 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
128
129 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
130 dict.get(), PermissionUtil::GetPermissionString(permission));
131
132 int current_count = 0;
133 permission_dict->GetInteger(kPromptDismissCountKey, &current_count);
134 permission_dict->SetInteger(kPromptDismissCountKey, ++current_count);
135
136 map->SetWebsiteSettingDefaultScope(
137 url, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
138 std::string(), std::move(dict));
139
140 return current_count;
141 }
142
143 void PermissionDecisionAutoBlocker::UpdateFromVariations() {
144 int prompt_dismissals = -1;
145 std::string value = variations::GetVariationParamValueByFeature(
146 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey);
147
148 // If converting the value fails, stick with the default value.
149 if (base::StringToInt(value, &prompt_dismissals) && prompt_dismissals > 0)
150 prompt_dismissals_before_block_ = prompt_dismissals;
151 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698