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

Side by Side Diff: chrome/browser/permissions/permission_prompt_decision_log.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: Unify implementation in permission_context_base, make log static 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_prompt_decision_log.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 int kPromptDismissalsBeforeBlock = 3;
raymes 2016/08/05 03:27:48 nit: const int
dominickn 2016/08/05 04:29:30 Done.
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 PermissionPromptDecisionLog::kPromptDismissCountKey[] =
61 "dismiss_count";
62
63 // static
64 void PermissionPromptDecisionLog::RemoveCountsByUrl(
65 Profile* profile,
66 base::Callback<bool(const GURL& url)> filter) {
67 HostContentSettingsMap* map =
68 HostContentSettingsMapFactory::GetForProfile(profile);
69
70 std::unique_ptr<ContentSettingsForOneType> settings(
71 new ContentSettingsForOneType);
72 map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
73 std::string(), settings.get());
74
75 for (const auto& site : *settings) {
76 GURL origin(site.primary_pattern.ToString());
77
78 if (origin.is_valid() && filter.Run(origin)) {
79 map->SetWebsiteSettingDefaultScope(
80 origin, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
81 std::string(), nullptr);
82 }
83 }
84 }
85
86 PermissionPromptDecisionLog::PermissionPromptDecisionLog()
87 : prompt_dismissals_before_block_(kPromptDismissalsBeforeBlock) {
88 UpdateFromVariations();
89 }
90
91 bool PermissionPromptDecisionLog::ShouldChangeDismissalToBlock(
92 Profile* profile,
93 const GURL& url,
94 content::PermissionType permission) {
95 int current_dismissal_count = RecordDismissalCount(profile, url, permission);
96
97 // |current_dismissal_count| is always (count_before_this_dismissal + 1)
raymes 2016/08/05 03:27:48 nit: What's count_before_this_dismissal? Maybe jus
dominickn 2016/08/05 04:29:30 Done.
98 PermissionUmaUtil::PermissionPromptDismissCount(permission,
99 current_dismissal_count - 1);
100
101 if (!base::FeatureList::IsEnabled(features::kBlockPromptsIfDismissedOften))
102 return false;
103
104 return current_dismissal_count >= prompt_dismissals_before_block_;
105 }
106
107 // static
108 int PermissionPromptDecisionLog::GetDismissalCount(
109 Profile* profile,
110 const GURL& url,
111 content::PermissionType permission) {
raymes 2016/08/05 03:27:48 Since this code is only used in the test, I'd sugg
dominickn 2016/08/05 04:29:30 Both GetOriginDict() and GetOrCreatePermissionDict
raymes 2016/08/06 00:50:21 Ah that makes sense. In that case we always suffix
dominickn 2016/08/08 02:18:28 Done.
112 HostContentSettingsMap* map =
113 HostContentSettingsMapFactory::GetForProfile(profile);
114 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
115
116 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
117 dict.get(), PermissionUtil::GetPermissionString(permission));
118
119 int current_count = 0;
120 permission_dict->GetInteger(
121 PermissionPromptDecisionLog::kPromptDismissCountKey, &current_count);
raymes 2016/08/05 03:27:48 nit: shouldn't need PermissionPromptDecisionLog::
dominickn 2016/08/05 04:29:30 Done.
122 return current_count;
123 }
124
125 // static
126 int PermissionPromptDecisionLog::RecordDismissalCount(
127 Profile* profile,
128 const GURL& url,
129 content::PermissionType permission) {
130 HostContentSettingsMap* map =
131 HostContentSettingsMapFactory::GetForProfile(profile);
132 std::unique_ptr<base::DictionaryValue> dict = GetOriginDict(map, url);
133
134 base::DictionaryValue* permission_dict = GetOrCreatePermissionDict(
135 dict.get(), PermissionUtil::GetPermissionString(permission));
136
137 int current_count = 0;
138 permission_dict->GetInteger(
139 PermissionPromptDecisionLog::kPromptDismissCountKey, &current_count);
140 permission_dict->SetInteger(
141 PermissionPromptDecisionLog::kPromptDismissCountKey, ++current_count);
raymes 2016/08/05 03:27:48 nit: same here and above
dominickn 2016/08/05 04:29:30 Done.
142
143 map->SetWebsiteSettingDefaultScope(
144 url, GURL(), CONTENT_SETTINGS_TYPE_PROMPT_NO_DECISION_COUNT,
145 std::string(), std::move(dict));
146
147 return current_count;
148 }
149
150 void PermissionPromptDecisionLog::UpdateFromVariations() {
151 int prompt_dismissals = -1;
152 std::string value = variations::GetVariationParamValueByFeature(
153 features::kBlockPromptsIfDismissedOften, kPromptDismissCountKey);
154
155 // If converting the value fails, stick with the default value.
156 if (base::StringToInt(value, &prompt_dismissals) && prompt_dismissals > 0)
157 prompt_dismissals_before_block_ = prompt_dismissals;
158 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698