1 // Copyright (c) 2011 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.
4
5 #include "chrome/browser/autofill/autofill_metrics.h"
6
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "chrome/browser/autofill/autofill_type.h"
10
11 namespace {
12
13 enum FieldTypeGroupForMetrics {
14 AMBIGUOUS = 0,
15 NAME,
16 COMPANY,
17 ADDRESS_LINE_1,
18 ADDRESS_LINE_2,
19 ADDRESS_CITY,
20 ADDRESS_STATE,
21 ADDRESS_ZIP,
22 ADDRESS_COUNTRY,
23 PHONE,
24 FAX,
25 EMAIL,
26 CREDIT_CARD_NAME,
27 CREDIT_CARD_NUMBER,
28 CREDIT_CARD_DATE,
29 NUM_FIELD_TYPE_GROUPS_FOR_METRICS
30 };
31
32 // Translates |field_type| to the corresponding logical grouping for metrics,
33 // and then interpolates this with the given |metric|, which should be in the
34 // range [0, |num_possible_metrics|). Returns the interpolated metric.
35 // Clients must ensure that |field_type| is one of the types Chrome supports
36 // natively, e.g. |field_type| must not be a billng address.
GetFieldTypeGroupMetric(const AutofillFieldType field_type,const int metric,const int num_possible_metrics)37 int GetFieldTypeGroupMetric(const AutofillFieldType field_type,
38 const int metric,
39 const int num_possible_metrics) {
40 DCHECK(metric < num_possible_metrics);
41
42 FieldTypeGroupForMetrics group;
43 switch (AutofillType(field_type).group()) {
44 case AutofillType::NO_GROUP:
45 group = AMBIGUOUS;
46 break;
47
48 case AutofillType::NAME:
49 group = NAME;
50 break;
51
52 case AutofillType::COMPANY:
53 group = COMPANY;
54 break;
55
56 case AutofillType::ADDRESS_HOME:
57 switch (field_type) {
58 case ADDRESS_HOME_LINE1:
59 group = ADDRESS_LINE_1;
60 break;
61 case ADDRESS_HOME_LINE2:
62 group = ADDRESS_LINE_2;
63 break;
64 case ADDRESS_HOME_CITY:
65 group = ADDRESS_CITY;
66 break;
67 case ADDRESS_HOME_STATE:
68 group = ADDRESS_STATE;
69 break;
70 case ADDRESS_HOME_ZIP:
71 group = ADDRESS_ZIP;
72 break;
73 case ADDRESS_HOME_COUNTRY:
74 group = ADDRESS_COUNTRY;
75 break;
76 default:
77 NOTREACHED();
78 group = AMBIGUOUS;
79 }
80 break;
81
82 case AutofillType::EMAIL:
83 group = EMAIL;
84 break;
85
86 case AutofillType::PHONE_HOME:
87 group = PHONE;
88 break;
89
90 case AutofillType::PHONE_FAX:
91 group = FAX;
92 break;
93
94 case AutofillType::CREDIT_CARD:
95 switch (field_type) {
96 case ::CREDIT_CARD_NAME:
97 group = CREDIT_CARD_NAME;
98 break;
99 case ::CREDIT_CARD_NUMBER:
100 group = CREDIT_CARD_NUMBER;
101 break;
102 default:
103 group = CREDIT_CARD_DATE;
104 }
105 break;
106
107 default:
108 NOTREACHED();
109 group = AMBIGUOUS;
110 }
111
112 // Interpolate the |metric| with the |group|, so that all metrics for a given
113 // |group| are adjacent. The resulting metrics will be arranged as:
114 // AMBIGUOUS_UNKNOWN
115 // AMBIGUOUS_MATCH
116 // AMBIGUOUS_MISMATCH
117 // NAME_UNKNOWN
118 // NAME_MATCH
119 // NAME_MISMATCH
120 // ...
121 return (group * num_possible_metrics) + metric;
122 }
123
124 // A version of the UMA_HISTOGRAM_ENUMERATION macro that allows the |name|
125 // to vary over the program's runtime.
LogUMAHistogramEnumeration(const std::string & name,int sample,int boundary_value)126 void LogUMAHistogramEnumeration(const std::string& name,
127 int sample,
128 int boundary_value) {
129 // We can't use the UMA_HISTOGRAM_ENUMERATION macro here because the histogram
130 // name can vary over the duration of the program.
131 // Note that this leaks memory; that is expected behavior.
132 base::Histogram* counter =
133 base::LinearHistogram::FactoryGet(
134 name,
135 1,
136 boundary_value,
137 boundary_value + 1,
138 base::Histogram::kUmaTargetedHistogramFlag);
139 counter->Add(sample);
140 }
141
142 // Logs a type quality metric. The primary histogram name is constructed based
143 // on |base_name| and |experiment_id|. The field-specific histogram name also
144 // factors in the |field_type|. Logs a sample of |metric|, which should be in
145 // the range [0, |num_possible_metrics|).
LogTypeQualityMetric(const std::string & base_name,const int metric,const int num_possible_metrics,const AutofillFieldType field_type,const std::string & experiment_id)146 void LogTypeQualityMetric(const std::string& base_name,
147 const int metric,
148 const int num_possible_metrics,
149 const AutofillFieldType field_type,
150 const std::string& experiment_id) {
151 DCHECK(metric < num_possible_metrics);
152
153 std::string histogram_name = base_name;
154 if (!experiment_id.empty())
155 histogram_name += "_" + experiment_id;
156 LogUMAHistogramEnumeration(histogram_name, metric, num_possible_metrics);
157
158 std::string sub_histogram_name = base_name + ".ByFieldType";
159 if (!experiment_id.empty())
160 sub_histogram_name += "_" + experiment_id;
161 const int field_type_group_metric =
162 GetFieldTypeGroupMetric(field_type, metric, num_possible_metrics);
163 const int num_field_type_group_metrics =
164 num_possible_metrics * NUM_FIELD_TYPE_GROUPS_FOR_METRICS;
165 LogUMAHistogramEnumeration(sub_histogram_name,
166 field_type_group_metric,
167 num_field_type_group_metrics);
168 }
169
170 } // namespace
171
AutofillMetrics()172 AutofillMetrics::AutofillMetrics() {
173 }
174
~AutofillMetrics()175 AutofillMetrics::~AutofillMetrics() {
176 }
177
Log(CreditCardInfoBarMetric metric) const178 void AutofillMetrics::Log(CreditCardInfoBarMetric metric) const {
179 DCHECK(metric < NUM_CREDIT_CARD_INFO_BAR_METRICS);
180
181 UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar", metric,
182 NUM_CREDIT_CARD_INFO_BAR_METRICS);
183 }
184
Log(HeuristicTypeQualityMetric metric,AutofillFieldType field_type,const std::string & experiment_id) const185 void AutofillMetrics::Log(HeuristicTypeQualityMetric metric,
186 AutofillFieldType field_type,
187 const std::string& experiment_id) const {
188 LogTypeQualityMetric("Autofill.Quality.HeuristicType",
189 metric, NUM_HEURISTIC_TYPE_QUALITY_METRICS,
190 field_type, experiment_id);
191 }
192
Log(PredictedTypeQualityMetric metric,AutofillFieldType field_type,const std::string & experiment_id) const193 void AutofillMetrics::Log(PredictedTypeQualityMetric metric,
194 AutofillFieldType field_type,
195 const std::string& experiment_id) const {
196 LogTypeQualityMetric("Autofill.Quality.PredictedType",
197 metric, NUM_PREDICTED_TYPE_QUALITY_METRICS,
198 field_type, experiment_id);
199 }
200
Log(QualityMetric metric,const std::string & experiment_id) const201 void AutofillMetrics::Log(QualityMetric metric,
202 const std::string& experiment_id) const {
203 DCHECK(metric < NUM_QUALITY_METRICS);
204
205 std::string histogram_name = "Autofill.Quality";
206 if (!experiment_id.empty())
207 histogram_name += "_" + experiment_id;
208
209 LogUMAHistogramEnumeration(histogram_name, metric, NUM_QUALITY_METRICS);
210 }
211
Log(ServerQueryMetric metric) const212 void AutofillMetrics::Log(ServerQueryMetric metric) const {
213 DCHECK(metric < NUM_SERVER_QUERY_METRICS);
214
215 UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric,
216 NUM_SERVER_QUERY_METRICS);
217 }
218
Log(ServerTypeQualityMetric metric,AutofillFieldType field_type,const std::string & experiment_id) const219 void AutofillMetrics::Log(ServerTypeQualityMetric metric,
220 AutofillFieldType field_type,
221 const std::string& experiment_id) const {
222 LogTypeQualityMetric("Autofill.Quality.ServerType",
223 metric, NUM_SERVER_TYPE_QUALITY_METRICS,
224 field_type, experiment_id);
225 }
226
LogIsAutofillEnabledAtStartup(bool enabled) const227 void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled) const {
228 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled);
229 }
230
LogIsAutofillEnabledAtPageLoad(bool enabled) const231 void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(bool enabled) const {
232 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.PageLoad", enabled);
233 }
234
LogStoredProfileCount(size_t num_profiles) const235 void AutofillMetrics::LogStoredProfileCount(size_t num_profiles) const {
236 UMA_HISTOGRAM_COUNTS("Autofill.StoredProfileCount", num_profiles);
237 }
238
LogAddressSuggestionsCount(size_t num_suggestions) const239 void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) const {
240 UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions);
241 }
242