OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/security_interstitials/core/metrics_helper.h" | 5 #include "components/security_interstitials/core/metrics_helper.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/metrics/user_metrics.h" | 11 #include "base/metrics/user_metrics.h" |
12 #include "base/metrics/user_metrics_action.h" | 12 #include "base/metrics/user_metrics_action.h" |
13 #include "components/history/core/browser/history_service.h" | 13 #include "components/history/core/browser/history_service.h" |
14 #include "components/rappor/public/rappor_utils.h" | |
15 #include "components/rappor/rappor_service_impl.h" | |
16 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 14 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
17 | 15 |
18 using base::RecordAction; | 16 using base::RecordAction; |
19 using base::UserMetricsAction; | 17 using base::UserMetricsAction; |
20 | 18 |
21 namespace security_interstitials { | 19 namespace security_interstitials { |
22 | 20 |
23 namespace { | 21 namespace { |
24 | 22 |
25 // Used for setting bits in Rappor's "interstitial.*.flags" | |
26 enum InterstitialFlagBits { | |
27 DID_PROCEED = 0, | |
28 IS_REPEAT_VISIT = 1, | |
29 HIGHEST_USED_BIT = 1 | |
30 }; | |
31 | |
32 // Directly adds to the UMA histograms, using the same properties as | 23 // Directly adds to the UMA histograms, using the same properties as |
33 // UMA_HISTOGRAM_ENUMERATION, because the macro doesn't allow non-constant | 24 // UMA_HISTOGRAM_ENUMERATION, because the macro doesn't allow non-constant |
34 // histogram names. | 25 // histogram names. |
35 void RecordSingleDecisionToMetrics(MetricsHelper::Decision decision, | 26 void RecordSingleDecisionToMetrics(MetricsHelper::Decision decision, |
36 const std::string& histogram_name) { | 27 const std::string& histogram_name) { |
37 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( | 28 base::HistogramBase* histogram = base::LinearHistogram::FactoryGet( |
38 histogram_name, 1, MetricsHelper::MAX_DECISION, | 29 histogram_name, 1, MetricsHelper::MAX_DECISION, |
39 MetricsHelper::MAX_DECISION + 1, | 30 MetricsHelper::MAX_DECISION + 1, |
40 base::HistogramBase::kUmaTargetedHistogramFlag); | 31 base::HistogramBase::kUmaTargetedHistogramFlag); |
41 histogram->Add(decision); | 32 histogram->Add(decision); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 } else if (interaction == MetricsHelper::OPEN_TIME_SETTINGS) { | 92 } else if (interaction == MetricsHelper::OPEN_TIME_SETTINGS) { |
102 if (metric_name == "bad_clock") | 93 if (metric_name == "bad_clock") |
103 RecordAction(UserMetricsAction("BadClockInterstitial.Settings")); | 94 RecordAction(UserMetricsAction("BadClockInterstitial.Settings")); |
104 } | 95 } |
105 } | 96 } |
106 | 97 |
107 } // namespace | 98 } // namespace |
108 | 99 |
109 MetricsHelper::~MetricsHelper() {} | 100 MetricsHelper::~MetricsHelper() {} |
110 | 101 |
111 MetricsHelper::ReportDetails::ReportDetails() | 102 MetricsHelper::ReportDetails::ReportDetails() {} |
112 : rappor_report_type(rappor::NUM_RAPPOR_TYPES) {} | |
113 | 103 |
114 MetricsHelper::ReportDetails::ReportDetails(const ReportDetails& other) = | 104 MetricsHelper::ReportDetails::ReportDetails(const ReportDetails& other) = |
115 default; | 105 default; |
116 | 106 |
117 MetricsHelper::ReportDetails::~ReportDetails() {} | 107 MetricsHelper::ReportDetails::~ReportDetails() {} |
118 | 108 |
119 MetricsHelper::MetricsHelper( | 109 MetricsHelper::MetricsHelper( |
120 const GURL& request_url, | 110 const GURL& request_url, |
121 const ReportDetails settings, | 111 const ReportDetails settings, |
122 history::HistoryService* history_service, | 112 history::HistoryService* history_service) |
123 const base::WeakPtr<rappor::RapporService>& rappor_service) | |
124 : request_url_(request_url), | 113 : request_url_(request_url), |
125 settings_(settings), | 114 settings_(settings), |
126 rappor_service_(rappor_service), | |
127 num_visits_(-1) { | 115 num_visits_(-1) { |
128 DCHECK(!settings_.metric_prefix.empty()); | 116 DCHECK(!settings_.metric_prefix.empty()); |
129 if (settings_.rappor_report_type == rappor::NUM_RAPPOR_TYPES) // Default. | |
130 rappor_service_.reset(); | |
131 DCHECK(!rappor_service_ || !settings_.rappor_prefix.empty()); | |
132 if (history_service) { | 117 if (history_service) { |
133 history_service->GetVisibleVisitCountToHost( | 118 history_service->GetVisibleVisitCountToHost( |
134 request_url_, | 119 request_url_, |
135 base::Bind(&MetricsHelper::OnGotHistoryCount, base::Unretained(this)), | 120 base::Bind(&MetricsHelper::OnGotHistoryCount, base::Unretained(this)), |
136 &request_tracker_); | 121 &request_tracker_); |
137 } | 122 } |
138 } | 123 } |
139 | 124 |
140 void MetricsHelper::RecordUserDecision(Decision decision) { | 125 void MetricsHelper::RecordUserDecision(Decision decision) { |
141 const std::string histogram_name( | 126 const std::string histogram_name( |
142 "interstitial." + settings_.metric_prefix + ".decision"); | 127 "interstitial." + settings_.metric_prefix + ".decision"); |
143 RecordUserDecisionToMetrics(decision, histogram_name); | 128 RecordUserDecisionToMetrics(decision, histogram_name); |
144 // Record additional information about sites that users have visited before. | 129 // Record additional information about sites that users have visited before. |
145 // Report |decision| and SHOW together, filtered by the same history state | 130 // Report |decision| and SHOW together, filtered by the same history state |
146 // so they they are paired regardless of when if num_visits_ is populated. | 131 // so they they are paired regardless of when if num_visits_ is populated. |
147 if (num_visits_ > 0 && (decision == PROCEED || decision == DONT_PROCEED)) { | 132 if (num_visits_ > 0 && (decision == PROCEED || decision == DONT_PROCEED)) { |
148 RecordUserDecisionToMetrics(SHOW, histogram_name + ".repeat_visit"); | 133 RecordUserDecisionToMetrics(SHOW, histogram_name + ".repeat_visit"); |
149 RecordUserDecisionToMetrics(decision, histogram_name + ".repeat_visit"); | 134 RecordUserDecisionToMetrics(decision, histogram_name + ".repeat_visit"); |
150 } | 135 } |
151 | 136 |
152 MaybeRecordDecisionAsAction(decision, settings_.metric_prefix); | 137 MaybeRecordDecisionAsAction(decision, settings_.metric_prefix); |
153 RecordUserDecisionToRappor(decision, settings_.rappor_report_type, | |
154 settings_.rappor_prefix); | |
155 RecordUserDecisionToRappor(decision, settings_.deprecated_rappor_report_type, | |
156 settings_.deprecated_rappor_prefix); | |
157 RecordExtraUserDecisionMetrics(decision); | 138 RecordExtraUserDecisionMetrics(decision); |
158 } | 139 } |
159 | 140 |
160 void MetricsHelper::RecordUserDecisionToMetrics( | 141 void MetricsHelper::RecordUserDecisionToMetrics( |
161 Decision decision, | 142 Decision decision, |
162 const std::string& histogram_name) { | 143 const std::string& histogram_name) { |
163 // Record the decision, and additionally |with extra_suffix|. | 144 // Record the decision, and additionally |with extra_suffix|. |
164 RecordSingleDecisionToMetrics(decision, histogram_name); | 145 RecordSingleDecisionToMetrics(decision, histogram_name); |
165 if (!settings_.extra_suffix.empty()) { | 146 if (!settings_.extra_suffix.empty()) { |
166 RecordSingleDecisionToMetrics( | 147 RecordSingleDecisionToMetrics( |
167 decision, histogram_name + "." + settings_.extra_suffix); | 148 decision, histogram_name + "." + settings_.extra_suffix); |
168 } | 149 } |
169 } | 150 } |
170 | 151 |
171 void MetricsHelper::RecordUserDecisionToRappor( | |
172 Decision decision, | |
173 const rappor::RapporType rappor_report_type, | |
174 const std::string& rappor_prefix) { | |
175 if (!rappor_service_ || (decision != PROCEED && decision != DONT_PROCEED)) | |
176 return; | |
177 | |
178 std::unique_ptr<rappor::Sample> sample = | |
179 rappor_service_->CreateSample(rappor_report_type); | |
180 | |
181 // This will populate, for example, "intersitial.malware2.domain" or | |
182 // "interstitial.ssl3.domain". The domain will be empty for hosts w/o TLDs. | |
183 sample->SetStringField( | |
184 "domain", rappor::GetDomainAndRegistrySampleFromGURL(request_url_)); | |
185 | |
186 // Only report history and decision if we have history data. | |
187 if (num_visits_ >= 0) { | |
188 int flags = 0; | |
189 if (decision == PROCEED) | |
190 flags |= 1 << InterstitialFlagBits::DID_PROCEED; | |
191 if (num_visits_ > 0) | |
192 flags |= 1 << InterstitialFlagBits::IS_REPEAT_VISIT; | |
193 // e.g. "interstitial.malware.flags" | |
194 sample->SetFlagsField("flags", flags, | |
195 InterstitialFlagBits::HIGHEST_USED_BIT + 1); | |
196 } | |
197 rappor_service_->RecordSample("interstitial." + rappor_prefix, | |
198 std::move(sample)); | |
199 } | |
200 | |
201 void MetricsHelper::RecordUserInteraction(Interaction interaction) { | 152 void MetricsHelper::RecordUserInteraction(Interaction interaction) { |
202 const std::string histogram_name( | 153 const std::string histogram_name( |
203 "interstitial." + settings_.metric_prefix + ".interaction"); | 154 "interstitial." + settings_.metric_prefix + ".interaction"); |
204 RecordSingleInteractionToMetrics(interaction, histogram_name); | 155 RecordSingleInteractionToMetrics(interaction, histogram_name); |
205 if (!settings_.extra_suffix.empty()) { | 156 if (!settings_.extra_suffix.empty()) { |
206 RecordSingleInteractionToMetrics( | 157 RecordSingleInteractionToMetrics( |
207 interaction, histogram_name + "." + settings_.extra_suffix); | 158 interaction, histogram_name + "." + settings_.extra_suffix); |
208 } | 159 } |
209 | 160 |
210 MaybeRecordInteractionAsAction(interaction, settings_.metric_prefix); | 161 MaybeRecordInteractionAsAction(interaction, settings_.metric_prefix); |
211 RecordExtraUserInteractionMetrics(interaction); | 162 RecordExtraUserInteractionMetrics(interaction); |
212 } | 163 } |
213 | 164 |
214 void MetricsHelper::RecordShutdownMetrics() { | 165 void MetricsHelper::RecordShutdownMetrics() { |
215 RecordExtraShutdownMetrics(); | 166 RecordExtraShutdownMetrics(); |
216 } | 167 } |
217 | 168 |
218 int MetricsHelper::NumVisits() { | 169 int MetricsHelper::NumVisits() { |
219 return num_visits_; | 170 return num_visits_; |
220 } | 171 } |
221 | 172 |
222 void MetricsHelper::OnGotHistoryCount(bool success, | 173 void MetricsHelper::OnGotHistoryCount(bool success, |
223 int num_visits, | 174 int num_visits, |
224 base::Time /*first_visit*/) { | 175 base::Time /*first_visit*/) { |
225 if (success) | 176 if (success) |
226 num_visits_ = num_visits; | 177 num_visits_ = num_visits; |
227 } | 178 } |
228 | 179 |
229 } // namespace security_interstitials | 180 } // namespace security_interstitials |
OLD | NEW |