Allow script to request durable storage permission (chrome side)
[chromium-blink-merge.git] / chrome / browser / permissions / permission_context_uma_util.cc
blob1e04d0c56d06cd1c0f6efea15dc063031d8844f1
1 // Copyright 2014 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.
5 #include "chrome/browser/permissions/permission_context_uma_util.h"
7 #include "base/metrics/histogram_macros.h"
8 #include "base/strings/stringprintf.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/permissions/permission_manager.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "components/rappor/rappor_utils.h"
13 #include "content/public/browser/permission_type.h"
14 #include "content/public/common/origin_util.h"
15 #include "url/gurl.h"
17 // UMA keys need to be statically initialized so plain function would not
18 // work. Use a Macro instead.
19 #define PERMISSION_ACTION_UMA(secure_origin, permission, permission_secure, \
20 permission_insecure, action) \
21 UMA_HISTOGRAM_ENUMERATION(permission, action, PERMISSION_ACTION_NUM); \
22 if (secure_origin) { \
23 UMA_HISTOGRAM_ENUMERATION(permission_secure, action, \
24 PERMISSION_ACTION_NUM); \
25 } else { \
26 UMA_HISTOGRAM_ENUMERATION(permission_insecure, action, \
27 PERMISSION_ACTION_NUM); \
30 using content::PermissionType;
32 namespace {
34 // Enum for UMA purposes, make sure you update histograms.xml if you add new
35 // permission actions. Never delete or reorder an entry; only add new entries
36 // immediately before PERMISSION_NUM
37 enum PermissionAction {
38 GRANTED = 0,
39 DENIED = 1,
40 DISMISSED = 2,
41 IGNORED = 3,
43 // Always keep this at the end.
44 PERMISSION_ACTION_NUM,
47 const std::string GetRapporMetric(ContentSettingsType permission,
48 PermissionAction action) {
49 std::string action_str;
50 switch (action) {
51 case GRANTED:
52 action_str = "Granted";
53 break;
54 case DENIED:
55 action_str = "Denied";
56 break;
57 case DISMISSED:
58 action_str = "Dismissed";
59 break;
60 case IGNORED:
61 action_str = "Ignored";
62 break;
63 case PERMISSION_ACTION_NUM:
64 NOTREACHED();
65 break;
67 std::string permission_str;
68 switch (permission) {
69 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
70 permission_str = "Geolocation";
71 break;
72 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
73 permission_str = "Notifications";
74 break;
75 default:
76 permission_str = "";
77 break;
80 if (permission_str.empty())
81 return "";
82 return base::StringPrintf("ContentSettings.PermissionActions_%s.%s.Url",
83 permission_str.c_str(), action_str.c_str());
86 void RecordPermissionAction(ContentSettingsType permission,
87 PermissionAction action,
88 const GURL& requesting_origin) {
89 bool secure_origin = content::IsOriginSecure(requesting_origin);
91 switch (permission) {
92 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
93 PERMISSION_ACTION_UMA(
94 secure_origin,
95 "ContentSettings.PermissionActions_Geolocation",
96 "ContentSettings.PermissionActionsSecureOrigin_Geolocation",
97 "ContentSettings.PermissionActionsInsecureOrigin_Geolocation",
98 action);
99 break;
100 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
101 PERMISSION_ACTION_UMA(
102 secure_origin,
103 "ContentSettings.PermissionActions_Notifications",
104 "ContentSettings.PermissionActionsSecureOrigin_Notifications",
105 "ContentSettings.PermissionActionsInsecureOrigin_Notifications",
106 action);
107 break;
108 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
109 PERMISSION_ACTION_UMA(
110 secure_origin,
111 "ContentSettings.PermissionActions_MidiSysEx",
112 "ContentSettings.PermissionActionsSecureOrigin_MidiSysEx",
113 "ContentSettings.PermissionActionsInsecureOrigin_MidiSysEx",
114 action);
115 break;
116 case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING:
117 PERMISSION_ACTION_UMA(
118 secure_origin,
119 "ContentSettings.PermissionActions_PushMessaging",
120 "ContentSettings.PermissionActionsSecureOrigin_PushMessaging",
121 "ContentSettings.PermissionActionsInsecureOrigin_PushMessaging",
122 action);
123 break;
124 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
125 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
126 PERMISSION_ACTION_UMA(
127 secure_origin,
128 "ContentSettings.PermissionActions_ProtectedMedia",
129 "ContentSettings.PermissionActionsSecureOrigin_ProtectedMedia",
130 "ContentSettings.PermissionActionsInsecureOrigin_ProtectedMedia",
131 action);
132 break;
133 #endif
134 case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE:
135 PERMISSION_ACTION_UMA(
136 secure_origin, "ContentSettings.PermissionActions_DurableStorage",
137 "ContentSettings.PermissionActionsSecureOrigin_DurableStorage",
138 "ContentSettings.PermissionActionsInsecureOrigin_DurableStorage",
139 action);
140 break;
141 default:
142 NOTREACHED() << "PERMISSION " << permission << " not accounted for";
145 const std::string& rappor_metric = GetRapporMetric(permission, action);
146 if (!rappor_metric.empty())
147 rappor::SampleDomainAndRegistryFromGURL(
148 g_browser_process->rappor_service(), rappor_metric,
149 requesting_origin);
152 std::string PermissionTypeToString(PermissionType permission_type) {
153 switch (permission_type) {
154 case PermissionType::MIDI_SYSEX:
155 return "MidiSysex";
156 case PermissionType::PUSH_MESSAGING:
157 return "PushMessaging";
158 case PermissionType::NOTIFICATIONS:
159 return "Notifications";
160 case PermissionType::GEOLOCATION:
161 return "Geolocation";
162 case PermissionType::PROTECTED_MEDIA_IDENTIFIER:
163 return "ProtectedMediaIdentifier";
164 case PermissionType::DURABLE_STORAGE:
165 return "DurableStorage";
166 case PermissionType::MIDI:
167 return "Midi";
168 case PermissionType::NUM:
169 break;
171 NOTREACHED();
172 return std::string();
175 void RecordPermissionRequest(ContentSettingsType permission,
176 const GURL& requesting_origin,
177 const GURL& embedding_origin,
178 Profile* profile) {
179 bool secure_origin = content::IsOriginSecure(requesting_origin);
180 PermissionType type;
181 switch (permission) {
182 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
183 type = PermissionType::GEOLOCATION;
184 rappor::SampleDomainAndRegistryFromGURL(
185 g_browser_process->rappor_service(),
186 "ContentSettings.PermissionRequested.Geolocation.Url",
187 requesting_origin);
188 break;
189 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
190 type = PermissionType::NOTIFICATIONS;
191 rappor::SampleDomainAndRegistryFromGURL(
192 g_browser_process->rappor_service(),
193 "ContentSettings.PermissionRequested.Notifications.Url",
194 requesting_origin);
195 break;
196 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
197 type = PermissionType::MIDI_SYSEX;
198 break;
199 case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING:
200 type = PermissionType::PUSH_MESSAGING;
201 break;
202 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
203 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
204 type = PermissionType::PROTECTED_MEDIA_IDENTIFIER;
205 break;
206 #endif
207 case CONTENT_SETTINGS_TYPE_DURABLE_STORAGE:
208 type = content::PermissionType::DURABLE_STORAGE;
209 break;
210 default:
211 NOTREACHED() << "PERMISSION " << permission << " not accounted for";
212 return;
214 UMA_HISTOGRAM_ENUMERATION(
215 "ContentSettings.PermissionRequested",
216 static_cast<base::HistogramBase::Sample>(type),
217 static_cast<base::HistogramBase::Sample>(PermissionType::NUM));
218 if (secure_origin) {
219 UMA_HISTOGRAM_ENUMERATION(
220 "ContentSettings.PermissionRequested_SecureOrigin",
221 static_cast<base::HistogramBase::Sample>(type),
222 static_cast<base::HistogramBase::Sample>(PermissionType::NUM));
223 } else {
224 UMA_HISTOGRAM_ENUMERATION(
225 "ContentSettings.PermissionRequested_InsecureOrigin",
226 static_cast<base::HistogramBase::Sample>(type),
227 static_cast<base::HistogramBase::Sample>(PermissionType::NUM));
230 // In order to gauge the compatibility risk of implementing an improved
231 // iframe permissions security model, we would like to know the ratio of
232 // same-origin to cross-origin permission requests. Our estimate of this
233 // ratio could be somewhat biased by repeated requests coming from a
234 // single frame, but we expect this to be insignificant.
235 if (requesting_origin.GetOrigin() != embedding_origin.GetOrigin()) {
236 content::PermissionManager* manager = profile->GetPermissionManager();
237 if (!manager)
238 return;
239 content::PermissionStatus embedding_permission_status =
240 manager->GetPermissionStatus(type, embedding_origin, embedding_origin);
242 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet(
243 "Permissions.Requested.CrossOrigin_" + PermissionTypeToString(type), 1,
244 content::PERMISSION_STATUS_LAST, content::PERMISSION_STATUS_LAST + 1,
245 base::HistogramBase::kUmaTargetedHistogramFlag);
246 histogram->Add(embedding_permission_status);
247 } else {
248 UMA_HISTOGRAM_ENUMERATION(
249 "Permissions.Requested.SameOrigin",
250 static_cast<base::HistogramBase::Sample>(type),
251 static_cast<base::HistogramBase::Sample>(PermissionType::NUM));
255 } // namespace
257 // Make sure you update histograms.xml permission histogram_suffix if you
258 // add new permission
259 void PermissionContextUmaUtil::PermissionRequested(
260 ContentSettingsType permission,
261 const GURL& requesting_origin,
262 const GURL& embedding_origin,
263 Profile* profile) {
264 RecordPermissionRequest(permission, requesting_origin, embedding_origin,
265 profile);
268 void PermissionContextUmaUtil::PermissionGranted(
269 ContentSettingsType permission, const GURL& requesting_origin) {
270 RecordPermissionAction(permission, GRANTED, requesting_origin);
273 void PermissionContextUmaUtil::PermissionDenied(
274 ContentSettingsType permission, const GURL& requesting_origin) {
275 RecordPermissionAction(permission, DENIED, requesting_origin);
278 void PermissionContextUmaUtil::PermissionDismissed(
279 ContentSettingsType permission, const GURL& requesting_origin) {
280 RecordPermissionAction(permission, DISMISSED, requesting_origin);
283 void PermissionContextUmaUtil::PermissionIgnored(
284 ContentSettingsType permission, const GURL& requesting_origin) {
285 RecordPermissionAction(permission, IGNORED, requesting_origin);