• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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