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(const GURL& request_url, |
120 const GURL& request_url, | 110 const ReportDetails settings, |
121 const ReportDetails settings, | 111 history::HistoryService* history_service) |
122 history::HistoryService* history_service, | 112 : request_url_(request_url), settings_(settings), num_visits_(-1) { |
123 const base::WeakPtr<rappor::RapporService>& rappor_service) | |
124 : request_url_(request_url), | |
125 settings_(settings), | |
126 rappor_service_(rappor_service), | |
127 num_visits_(-1) { | |
128 DCHECK(!settings_.metric_prefix.empty()); | 113 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) { | 114 if (history_service) { |
133 history_service->GetVisibleVisitCountToHost( | 115 history_service->GetVisibleVisitCountToHost( |
134 request_url_, | 116 request_url_, |
135 base::Bind(&MetricsHelper::OnGotHistoryCount, base::Unretained(this)), | 117 base::Bind(&MetricsHelper::OnGotHistoryCount, base::Unretained(this)), |
136 &request_tracker_); | 118 &request_tracker_); |
137 } | 119 } |
138 } | 120 } |
139 | 121 |
140 void MetricsHelper::RecordUserDecision(Decision decision) { | 122 void MetricsHelper::RecordUserDecision(Decision decision) { |
141 const std::string histogram_name( | 123 const std::string histogram_name( |
142 "interstitial." + settings_.metric_prefix + ".decision"); | 124 "interstitial." + settings_.metric_prefix + ".decision"); |
143 RecordUserDecisionToMetrics(decision, histogram_name); | 125 RecordUserDecisionToMetrics(decision, histogram_name); |
144 // Record additional information about sites that users have visited before. | 126 // Record additional information about sites that users have visited before. |
145 // Report |decision| and SHOW together, filtered by the same history state | 127 // 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. | 128 // so they they are paired regardless of when if num_visits_ is populated. |
147 if (num_visits_ > 0 && (decision == PROCEED || decision == DONT_PROCEED)) { | 129 if (num_visits_ > 0 && (decision == PROCEED || decision == DONT_PROCEED)) { |
148 RecordUserDecisionToMetrics(SHOW, histogram_name + ".repeat_visit"); | 130 RecordUserDecisionToMetrics(SHOW, histogram_name + ".repeat_visit"); |
149 RecordUserDecisionToMetrics(decision, histogram_name + ".repeat_visit"); | 131 RecordUserDecisionToMetrics(decision, histogram_name + ".repeat_visit"); |
150 } | 132 } |
151 | 133 |
152 MaybeRecordDecisionAsAction(decision, settings_.metric_prefix); | 134 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); | 135 RecordExtraUserDecisionMetrics(decision); |
158 } | 136 } |
159 | 137 |
160 void MetricsHelper::RecordUserDecisionToMetrics( | 138 void MetricsHelper::RecordUserDecisionToMetrics( |
161 Decision decision, | 139 Decision decision, |
162 const std::string& histogram_name) { | 140 const std::string& histogram_name) { |
163 // Record the decision, and additionally |with extra_suffix|. | 141 // Record the decision, and additionally |with extra_suffix|. |
164 RecordSingleDecisionToMetrics(decision, histogram_name); | 142 RecordSingleDecisionToMetrics(decision, histogram_name); |
165 if (!settings_.extra_suffix.empty()) { | 143 if (!settings_.extra_suffix.empty()) { |
166 RecordSingleDecisionToMetrics( | 144 RecordSingleDecisionToMetrics( |
167 decision, histogram_name + "." + settings_.extra_suffix); | 145 decision, histogram_name + "." + settings_.extra_suffix); |
168 } | 146 } |
169 } | 147 } |
170 | 148 |
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) { | 149 void MetricsHelper::RecordUserInteraction(Interaction interaction) { |
202 const std::string histogram_name( | 150 const std::string histogram_name( |
203 "interstitial." + settings_.metric_prefix + ".interaction"); | 151 "interstitial." + settings_.metric_prefix + ".interaction"); |
204 RecordSingleInteractionToMetrics(interaction, histogram_name); | 152 RecordSingleInteractionToMetrics(interaction, histogram_name); |
205 if (!settings_.extra_suffix.empty()) { | 153 if (!settings_.extra_suffix.empty()) { |
206 RecordSingleInteractionToMetrics( | 154 RecordSingleInteractionToMetrics( |
207 interaction, histogram_name + "." + settings_.extra_suffix); | 155 interaction, histogram_name + "." + settings_.extra_suffix); |
208 } | 156 } |
209 | 157 |
210 MaybeRecordInteractionAsAction(interaction, settings_.metric_prefix); | 158 MaybeRecordInteractionAsAction(interaction, settings_.metric_prefix); |
211 RecordExtraUserInteractionMetrics(interaction); | 159 RecordExtraUserInteractionMetrics(interaction); |
212 } | 160 } |
213 | 161 |
214 void MetricsHelper::RecordShutdownMetrics() { | 162 void MetricsHelper::RecordShutdownMetrics() { |
215 RecordExtraShutdownMetrics(); | 163 RecordExtraShutdownMetrics(); |
216 } | 164 } |
217 | 165 |
218 int MetricsHelper::NumVisits() { | 166 int MetricsHelper::NumVisits() { |
219 return num_visits_; | 167 return num_visits_; |
220 } | 168 } |
221 | 169 |
222 void MetricsHelper::OnGotHistoryCount(bool success, | 170 void MetricsHelper::OnGotHistoryCount(bool success, |
223 int num_visits, | 171 int num_visits, |
224 base::Time /*first_visit*/) { | 172 base::Time /*first_visit*/) { |
225 if (success) | 173 if (success) |
226 num_visits_ = num_visits; | 174 num_visits_ = num_visits; |
227 } | 175 } |
228 | 176 |
229 } // namespace security_interstitials | 177 } // namespace security_interstitials |
OLD | NEW |