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"
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); \
26 UMA_HISTOGRAM_ENUMERATION(permission_insecure, action, \
27 PERMISSION_ACTION_NUM); \
30 using content::PermissionType
;
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
{
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
;
52 action_str
= "Granted";
55 action_str
= "Denied";
58 action_str
= "Dismissed";
61 action_str
= "Ignored";
63 case PERMISSION_ACTION_NUM
:
67 std::string permission_str
;
69 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
70 permission_str
= "Geolocation";
72 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
73 permission_str
= "Notifications";
80 if (permission_str
.empty())
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
);
92 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
93 PERMISSION_ACTION_UMA(
95 "ContentSettings.PermissionActions_Geolocation",
96 "ContentSettings.PermissionActionsSecureOrigin_Geolocation",
97 "ContentSettings.PermissionActionsInsecureOrigin_Geolocation",
100 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
101 PERMISSION_ACTION_UMA(
103 "ContentSettings.PermissionActions_Notifications",
104 "ContentSettings.PermissionActionsSecureOrigin_Notifications",
105 "ContentSettings.PermissionActionsInsecureOrigin_Notifications",
108 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX
:
109 PERMISSION_ACTION_UMA(
111 "ContentSettings.PermissionActions_MidiSysEx",
112 "ContentSettings.PermissionActionsSecureOrigin_MidiSysEx",
113 "ContentSettings.PermissionActionsInsecureOrigin_MidiSysEx",
116 case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
:
117 PERMISSION_ACTION_UMA(
119 "ContentSettings.PermissionActions_PushMessaging",
120 "ContentSettings.PermissionActionsSecureOrigin_PushMessaging",
121 "ContentSettings.PermissionActionsInsecureOrigin_PushMessaging",
124 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
125 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
:
126 PERMISSION_ACTION_UMA(
128 "ContentSettings.PermissionActions_ProtectedMedia",
129 "ContentSettings.PermissionActionsSecureOrigin_ProtectedMedia",
130 "ContentSettings.PermissionActionsInsecureOrigin_ProtectedMedia",
135 NOTREACHED() << "PERMISSION " << permission
<< " not accounted for";
138 const std::string
& rappor_metric
= GetRapporMetric(permission
, action
);
139 if (!rappor_metric
.empty())
140 rappor::SampleDomainAndRegistryFromGURL(
141 g_browser_process
->rappor_service(), rappor_metric
,
145 std::string
PermissionTypeToString(PermissionType permission_type
) {
146 switch (permission_type
) {
147 case PermissionType::MIDI_SYSEX
:
149 case PermissionType::PUSH_MESSAGING
:
150 return "PushMessaging";
151 case PermissionType::NOTIFICATIONS
:
152 return "Notifications";
153 case PermissionType::GEOLOCATION
:
154 return "Geolocation";
155 case PermissionType::PROTECTED_MEDIA_IDENTIFIER
:
156 return "ProtectedMediaIdentifier";
157 case PermissionType::NUM
:
161 return std::string();
164 void RecordPermissionRequest(ContentSettingsType permission
,
165 const GURL
& requesting_origin
,
166 const GURL
& embedding_origin
,
168 bool secure_origin
= content::IsOriginSecure(requesting_origin
);
170 switch (permission
) {
171 case CONTENT_SETTINGS_TYPE_GEOLOCATION
:
172 type
= PermissionType::GEOLOCATION
;
173 rappor::SampleDomainAndRegistryFromGURL(
174 g_browser_process
->rappor_service(),
175 "ContentSettings.PermissionRequested.Geolocation.Url",
178 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS
:
179 type
= PermissionType::NOTIFICATIONS
;
180 rappor::SampleDomainAndRegistryFromGURL(
181 g_browser_process
->rappor_service(),
182 "ContentSettings.PermissionRequested.Notifications.Url",
185 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX
:
186 type
= PermissionType::MIDI_SYSEX
;
188 case CONTENT_SETTINGS_TYPE_PUSH_MESSAGING
:
189 type
= PermissionType::PUSH_MESSAGING
;
191 #if defined(OS_ANDROID) || defined(OS_CHROMEOS)
192 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER
:
193 type
= PermissionType::PROTECTED_MEDIA_IDENTIFIER
;
197 NOTREACHED() << "PERMISSION " << permission
<< " not accounted for";
200 UMA_HISTOGRAM_ENUMERATION(
201 "ContentSettings.PermissionRequested",
202 static_cast<base::HistogramBase::Sample
>(type
),
203 static_cast<base::HistogramBase::Sample
>(PermissionType::NUM
));
205 UMA_HISTOGRAM_ENUMERATION(
206 "ContentSettings.PermissionRequested_SecureOrigin",
207 static_cast<base::HistogramBase::Sample
>(type
),
208 static_cast<base::HistogramBase::Sample
>(PermissionType::NUM
));
210 UMA_HISTOGRAM_ENUMERATION(
211 "ContentSettings.PermissionRequested_InsecureOrigin",
212 static_cast<base::HistogramBase::Sample
>(type
),
213 static_cast<base::HistogramBase::Sample
>(PermissionType::NUM
));
216 // In order to gauge the compatibility risk of implementing an improved
217 // iframe permissions security model, we would like to know the ratio of
218 // same-origin to cross-origin permission requests. Our estimate of this
219 // ratio could be somewhat biased by repeated requests coming from a
220 // single frame, but we expect this to be insignificant.
221 if (requesting_origin
.GetOrigin() != embedding_origin
.GetOrigin()) {
222 content::PermissionManager
* manager
= profile
->GetPermissionManager();
225 content::PermissionStatus embedding_permission_status
=
226 manager
->GetPermissionStatus(type
, embedding_origin
, embedding_origin
);
228 base::HistogramBase
* histogram
= base::LinearHistogram::FactoryGet(
229 "Permissions.Requested.CrossOrigin_" + PermissionTypeToString(type
), 1,
230 content::PERMISSION_STATUS_LAST
, content::PERMISSION_STATUS_LAST
+ 1,
231 base::HistogramBase::kUmaTargetedHistogramFlag
);
232 histogram
->Add(embedding_permission_status
);
234 UMA_HISTOGRAM_ENUMERATION(
235 "Permissions.Requested.SameOrigin",
236 static_cast<base::HistogramBase::Sample
>(type
),
237 static_cast<base::HistogramBase::Sample
>(PermissionType::NUM
));
243 // Make sure you update histograms.xml permission histogram_suffix if you
244 // add new permission
245 void PermissionContextUmaUtil::PermissionRequested(
246 ContentSettingsType permission
,
247 const GURL
& requesting_origin
,
248 const GURL
& embedding_origin
,
250 RecordPermissionRequest(permission
, requesting_origin
, embedding_origin
,
254 void PermissionContextUmaUtil::PermissionGranted(
255 ContentSettingsType permission
, const GURL
& requesting_origin
) {
256 RecordPermissionAction(permission
, GRANTED
, requesting_origin
);
259 void PermissionContextUmaUtil::PermissionDenied(
260 ContentSettingsType permission
, const GURL
& requesting_origin
) {
261 RecordPermissionAction(permission
, DENIED
, requesting_origin
);
264 void PermissionContextUmaUtil::PermissionDismissed(
265 ContentSettingsType permission
, const GURL
& requesting_origin
) {
266 RecordPermissionAction(permission
, DISMISSED
, requesting_origin
);
269 void PermissionContextUmaUtil::PermissionIgnored(
270 ContentSettingsType permission
, const GURL
& requesting_origin
) {
271 RecordPermissionAction(permission
, IGNORED
, requesting_origin
);