| 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 |