Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / autofill_metrics.cc
1 // Copyright 2013 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 "components/autofill/core/browser/autofill_metrics.h"
6
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "base/metrics/sparse_histogram.h"
10 #include "base/time/time.h"
11 #include "components/autofill/core/browser/autofill_type.h"
12 #include "components/autofill/core/browser/form_structure.h"
13 #include "components/autofill/core/common/form_data.h"
14
15 namespace autofill {
16
17 namespace {
18
19 enum FieldTypeGroupForMetrics {
20   AMBIGUOUS = 0,
21   NAME,
22   COMPANY,
23   ADDRESS_LINE_1,
24   ADDRESS_LINE_2,
25   ADDRESS_CITY,
26   ADDRESS_STATE,
27   ADDRESS_ZIP,
28   ADDRESS_COUNTRY,
29   PHONE,
30   FAX,  // Deprecated.
31   EMAIL,
32   CREDIT_CARD_NAME,
33   CREDIT_CARD_NUMBER,
34   CREDIT_CARD_DATE,
35   CREDIT_CARD_TYPE,
36   PASSWORD,
37   ADDRESS_LINE_3,
38   NUM_FIELD_TYPE_GROUPS_FOR_METRICS
39 };
40
41 // First, translates |field_type| to the corresponding logical |group| from
42 // |FieldTypeGroupForMetrics|.  Then, interpolates this with the given |metric|,
43 // which should be in the range [0, |num_possible_metrics|).
44 // Returns the interpolated index.
45 //
46 // The interpolation maps the pair (|group|, |metric|) to a single index, so
47 // that all the indicies for a given group are adjacent.  In particular, with
48 // the groups {AMBIGUOUS, NAME, ...} combining with the metrics {UNKNOWN, MATCH,
49 // MISMATCH}, we create this set of mapped indices:
50 // {
51 //   AMBIGUOUS+UNKNOWN,
52 //   AMBIGUOUS+MATCH,
53 //   AMBIGUOUS+MISMATCH,
54 //   NAME+UNKNOWN,
55 //   NAME+MATCH,
56 //   NAME+MISMATCH,
57 //   ...
58 // }.
59 //
60 // Clients must ensure that |field_type| is one of the types Chrome supports
61 // natively, e.g. |field_type| must not be a billng address.
62 int GetFieldTypeGroupMetric(const ServerFieldType field_type,
63                             const int metric,
64                             const int num_possible_metrics) {
65   DCHECK_LT(metric, num_possible_metrics);
66
67   FieldTypeGroupForMetrics group = AMBIGUOUS;
68   switch (AutofillType(field_type).group()) {
69     case ::autofill::NO_GROUP:
70       group = AMBIGUOUS;
71       break;
72
73     case ::autofill::NAME:
74     case ::autofill::NAME_BILLING:
75       group = NAME;
76       break;
77
78     case ::autofill::COMPANY:
79       group = COMPANY;
80       break;
81
82     case ::autofill::ADDRESS_HOME:
83     case ::autofill::ADDRESS_BILLING:
84       switch (AutofillType(field_type).GetStorableType()) {
85         case ADDRESS_HOME_LINE1:
86           group = ADDRESS_LINE_1;
87           break;
88         case ADDRESS_HOME_LINE2:
89           group = ADDRESS_LINE_2;
90           break;
91         case ADDRESS_HOME_LINE3:
92           group = ADDRESS_LINE_3;
93           break;
94         case ADDRESS_HOME_CITY:
95           group = ADDRESS_CITY;
96           break;
97         case ADDRESS_HOME_STATE:
98           group = ADDRESS_STATE;
99           break;
100         case ADDRESS_HOME_ZIP:
101           group = ADDRESS_ZIP;
102           break;
103         case ADDRESS_HOME_COUNTRY:
104           group = ADDRESS_COUNTRY;
105           break;
106         default:
107           NOTREACHED();
108           group = AMBIGUOUS;
109           break;
110       }
111       break;
112
113     case ::autofill::EMAIL:
114       group = EMAIL;
115       break;
116
117     case ::autofill::PHONE_HOME:
118     case ::autofill::PHONE_BILLING:
119       group = PHONE;
120       break;
121
122     case ::autofill::CREDIT_CARD:
123       switch (field_type) {
124         case ::autofill::CREDIT_CARD_NAME:
125           group = CREDIT_CARD_NAME;
126           break;
127         case ::autofill::CREDIT_CARD_NUMBER:
128           group = CREDIT_CARD_NUMBER;
129           break;
130         case ::autofill::CREDIT_CARD_TYPE:
131           group = CREDIT_CARD_TYPE;
132           break;
133         case ::autofill::CREDIT_CARD_EXP_MONTH:
134         case ::autofill::CREDIT_CARD_EXP_2_DIGIT_YEAR:
135         case ::autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR:
136         case ::autofill::CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR:
137         case ::autofill::CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR:
138           group = CREDIT_CARD_DATE;
139           break;
140         default:
141           NOTREACHED();
142           group = AMBIGUOUS;
143           break;
144       }
145       break;
146
147     case ::autofill::PASSWORD_FIELD:
148       group = PASSWORD;
149       break;
150
151     case ::autofill::TRANSACTION:
152       NOTREACHED();
153       break;
154   }
155
156   // Interpolate the |metric| with the |group|, so that all metrics for a given
157   // |group| are adjacent.
158   return (group * num_possible_metrics) + metric;
159 }
160
161 std::string WalletApiMetricToString(
162     AutofillMetrics::WalletApiCallMetric metric) {
163   switch (metric) {
164     case AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS:
165       return "AcceptLegalDocuments";
166     case AutofillMetrics::AUTHENTICATE_INSTRUMENT:
167       return "AuthenticateInstrument";
168     case AutofillMetrics::GET_FULL_WALLET:
169       return "GetFullWallet";
170     case AutofillMetrics::GET_WALLET_ITEMS:
171       return "GetWalletItems";
172     case AutofillMetrics::SAVE_TO_WALLET:
173       return "SaveToWallet";
174     case AutofillMetrics::UNKNOWN_API_CALL:
175     case AutofillMetrics::NUM_WALLET_API_CALLS:
176       NOTREACHED();
177       return "UnknownApiCall";
178   }
179
180   NOTREACHED();
181   return "UnknownApiCall";
182 }
183
184 // A version of the UMA_HISTOGRAM_ENUMERATION macro that allows the |name|
185 // to vary over the program's runtime.
186 void LogUMAHistogramEnumeration(const std::string& name,
187                                 int sample,
188                                 int boundary_value) {
189   DCHECK_LT(sample, boundary_value);
190
191   // Note: This leaks memory, which is expected behavior.
192   base::HistogramBase* histogram =
193       base::LinearHistogram::FactoryGet(
194           name,
195           1,
196           boundary_value,
197           boundary_value + 1,
198           base::HistogramBase::kUmaTargetedHistogramFlag);
199   histogram->Add(sample);
200 }
201
202 // A version of the UMA_HISTOGRAM_TIMES macro that allows the |name|
203 // to vary over the program's runtime.
204 void LogUMAHistogramTimes(const std::string& name,
205                           const base::TimeDelta& duration) {
206   // Note: This leaks memory, which is expected behavior.
207   base::HistogramBase* histogram =
208       base::Histogram::FactoryTimeGet(
209           name,
210           base::TimeDelta::FromMilliseconds(1),
211           base::TimeDelta::FromSeconds(10),
212           50,
213           base::HistogramBase::kUmaTargetedHistogramFlag);
214   histogram->AddTime(duration);
215 }
216
217 // A version of the UMA_HISTOGRAM_LONG_TIMES macro that allows the |name|
218 // to vary over the program's runtime.
219 void LogUMAHistogramLongTimes(const std::string& name,
220                               const base::TimeDelta& duration) {
221   // Note: This leaks memory, which is expected behavior.
222   base::HistogramBase* histogram =
223       base::Histogram::FactoryTimeGet(
224           name,
225           base::TimeDelta::FromMilliseconds(1),
226           base::TimeDelta::FromHours(1),
227           50,
228           base::HistogramBase::kUmaTargetedHistogramFlag);
229   histogram->AddTime(duration);
230 }
231
232 // Logs a type quality metric.  The primary histogram name is constructed based
233 // on |base_name|.  The field-specific histogram name also factors in the
234 // |field_type|.  Logs a sample of |metric|, which should be in the range
235 // [0, |num_possible_metrics|).
236 void LogTypeQualityMetric(const std::string& base_name,
237                           const int metric,
238                           const int num_possible_metrics,
239                           const ServerFieldType field_type) {
240   DCHECK_LT(metric, num_possible_metrics);
241
242   std::string histogram_name = base_name;
243   LogUMAHistogramEnumeration(histogram_name, metric, num_possible_metrics);
244
245   std::string sub_histogram_name = base_name + ".ByFieldType";
246   const int field_type_group_metric =
247       GetFieldTypeGroupMetric(field_type, metric, num_possible_metrics);
248   const int num_field_type_group_metrics =
249       num_possible_metrics * NUM_FIELD_TYPE_GROUPS_FOR_METRICS;
250   LogUMAHistogramEnumeration(sub_histogram_name,
251                              field_type_group_metric,
252                              num_field_type_group_metrics);
253 }
254
255 }  // namespace
256
257 AutofillMetrics::AutofillMetrics() {
258 }
259
260 AutofillMetrics::~AutofillMetrics() {
261 }
262
263 void AutofillMetrics::LogCreditCardInfoBarMetric(InfoBarMetric metric) const {
264   DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
265
266   UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar", metric,
267                             NUM_INFO_BAR_METRICS);
268 }
269
270 void AutofillMetrics::LogDialogDismissalState(
271     DialogDismissalState state) const {
272   UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.DismissalState",
273                             state, NUM_DIALOG_DISMISSAL_STATES);
274 }
275
276 void AutofillMetrics::LogDialogInitialUserState(
277     DialogInitialUserStateMetric user_type) const {
278   UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.InitialUserState",
279                             user_type, NUM_DIALOG_INITIAL_USER_STATE_METRICS);
280 }
281
282 void AutofillMetrics::LogDialogLatencyToShow(
283     const base::TimeDelta& duration) const {
284   LogUMAHistogramTimes("RequestAutocomplete.UiLatencyToShow", duration);
285 }
286
287 void AutofillMetrics::LogDialogPopupEvent(DialogPopupEvent event) const {
288   UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.PopupInDialog",
289                             event, NUM_DIALOG_POPUP_EVENTS);
290 }
291
292 void AutofillMetrics::LogDialogSecurityMetric(
293     DialogSecurityMetric metric) const {
294   UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.Security",
295                             metric, NUM_DIALOG_SECURITY_METRICS);
296 }
297
298 void AutofillMetrics::LogDialogUiDuration(
299     const base::TimeDelta& duration,
300     DialogDismissalAction dismissal_action) const {
301   std::string suffix;
302   switch (dismissal_action) {
303     case DIALOG_ACCEPTED:
304       suffix = "Submit";
305       break;
306
307     case DIALOG_CANCELED:
308       suffix = "Cancel";
309       break;
310   }
311
312   LogUMAHistogramLongTimes("RequestAutocomplete.UiDuration", duration);
313   LogUMAHistogramLongTimes("RequestAutocomplete.UiDuration." + suffix,
314                            duration);
315 }
316
317 void AutofillMetrics::LogDialogUiEvent(DialogUiEvent event) const {
318   UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.UiEvents", event,
319                             NUM_DIALOG_UI_EVENTS);
320 }
321
322 void AutofillMetrics::LogWalletErrorMetric(WalletErrorMetric metric) const {
323   UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.WalletErrors", metric,
324                             NUM_WALLET_ERROR_METRICS);
325 }
326
327 void AutofillMetrics::LogWalletApiCallDuration(
328     WalletApiCallMetric metric,
329     const base::TimeDelta& duration) const {
330   LogUMAHistogramTimes("Wallet.ApiCallDuration." +
331                        WalletApiMetricToString(metric), duration);
332 }
333
334 void AutofillMetrics::LogWalletMalformedResponseMetric(
335     WalletApiCallMetric metric) const {
336   UMA_HISTOGRAM_ENUMERATION("Wallet.MalformedResponse", metric,
337                             NUM_WALLET_API_CALLS);
338 }
339
340 void AutofillMetrics::LogWalletRequiredActionMetric(
341       WalletRequiredActionMetric required_action) const {
342   UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.WalletRequiredActions",
343                             required_action, NUM_WALLET_REQUIRED_ACTIONS);
344 }
345
346 void AutofillMetrics::LogWalletResponseCode(int response_code) const {
347   UMA_HISTOGRAM_SPARSE_SLOWLY("Wallet.ResponseCode", response_code);
348 }
349
350 void AutofillMetrics::LogDeveloperEngagementMetric(
351     DeveloperEngagementMetric metric) const {
352   DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS);
353
354   UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric,
355                             NUM_DEVELOPER_ENGAGEMENT_METRICS);
356 }
357
358 void AutofillMetrics::LogHeuristicTypePrediction(
359     FieldTypeQualityMetric metric,
360     ServerFieldType field_type) const {
361   LogTypeQualityMetric("Autofill.Quality.HeuristicType",
362                        metric, NUM_FIELD_TYPE_QUALITY_METRICS, field_type);
363 }
364
365 void AutofillMetrics::LogOverallTypePrediction(
366     FieldTypeQualityMetric metric,
367     ServerFieldType field_type) const {
368   LogTypeQualityMetric("Autofill.Quality.PredictedType",
369                        metric, NUM_FIELD_TYPE_QUALITY_METRICS, field_type);
370 }
371
372 void AutofillMetrics::LogServerTypePrediction(
373     FieldTypeQualityMetric metric,
374     ServerFieldType field_type) const {
375   LogTypeQualityMetric("Autofill.Quality.ServerType",
376                        metric, NUM_FIELD_TYPE_QUALITY_METRICS, field_type);
377 }
378
379 void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) const {
380   DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS);
381
382   UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric,
383                             NUM_SERVER_QUERY_METRICS);
384 }
385
386 void AutofillMetrics::LogUserHappinessMetric(UserHappinessMetric metric) const {
387   DCHECK_LT(metric, NUM_USER_HAPPINESS_METRICS);
388
389   UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness", metric,
390                             NUM_USER_HAPPINESS_METRICS);
391 }
392
393 void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill(
394     const base::TimeDelta& duration) const {
395   UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithAutofill",
396                              duration,
397                              base::TimeDelta::FromMilliseconds(100),
398                              base::TimeDelta::FromMinutes(10),
399                              50);
400 }
401
402 void AutofillMetrics::LogFormFillDurationFromLoadWithoutAutofill(
403     const base::TimeDelta& duration) const {
404   UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithoutAutofill",
405                              duration,
406                              base::TimeDelta::FromMilliseconds(100),
407                              base::TimeDelta::FromMinutes(10),
408                              50);
409 }
410
411 void AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill(
412     const base::TimeDelta& duration) const {
413   UMA_HISTOGRAM_CUSTOM_TIMES(
414       "Autofill.FillDuration.FromInteraction.WithAutofill",
415       duration,
416       base::TimeDelta::FromMilliseconds(100),
417       base::TimeDelta::FromMinutes(10),
418       50);
419 }
420
421 void AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill(
422     const base::TimeDelta& duration) const {
423   UMA_HISTOGRAM_CUSTOM_TIMES(
424        "Autofill.FillDuration.FromInteraction.WithoutAutofill",
425        duration,
426        base::TimeDelta::FromMilliseconds(100),
427        base::TimeDelta::FromMinutes(10),
428        50);
429 }
430
431 void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled) const {
432   UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled);
433 }
434
435 void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(bool enabled) const {
436   UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.PageLoad", enabled);
437 }
438
439 void AutofillMetrics::LogStoredProfileCount(size_t num_profiles) const {
440   UMA_HISTOGRAM_COUNTS("Autofill.StoredProfileCount", num_profiles);
441 }
442
443 void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) const {
444   UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions);
445 }
446
447 }  // namespace autofill