autofill_metrics.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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/time/time.h"
10#include "components/autofill/core/browser/autofill_type.h"
11#include "components/autofill/core/browser/form_structure.h"
12#include "components/autofill/core/common/form_data.h"
13
14namespace autofill {
15
16namespace {
17
18// Server experiments we support.
19enum ServerExperiment {
20  NO_EXPERIMENT = 0,
21  UNKNOWN_EXPERIMENT,
22  ACCEPTANCE_RATIO_06,
23  ACCEPTANCE_RATIO_1,
24  ACCEPTANCE_RATIO_2,
25  ACCEPTANCE_RATIO_4,
26  ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15,
27  ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_25,
28  ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15_MIN_FORM_SCORE_5,
29  TOOLBAR_DATA_ONLY,
30  ACCEPTANCE_RATIO_04_WINNER_LEAD_RATIO_3_MIN_FORM_SCORE_4,
31  NO_SERVER_RESPONSE,
32  PROBABILITY_PICKER_05,
33  PROBABILITY_PICKER_025,
34  PROBABILITY_PICKER_025_CC_THRESHOLD_03,
35  PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03,
36  PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03_WITH_FALLBACK,
37  PROBABILITY_PICKER_05_CC_NAME_THRESHOLD_03_EXPERIMENT_1,
38  NUM_SERVER_EXPERIMENTS
39};
40
41enum FieldTypeGroupForMetrics {
42  AMBIGUOUS = 0,
43  NAME,
44  COMPANY,
45  ADDRESS_LINE_1,
46  ADDRESS_LINE_2,
47  ADDRESS_CITY,
48  ADDRESS_STATE,
49  ADDRESS_ZIP,
50  ADDRESS_COUNTRY,
51  PHONE,
52  FAX,  // Deprecated.
53  EMAIL,
54  CREDIT_CARD_NAME,
55  CREDIT_CARD_NUMBER,
56  CREDIT_CARD_DATE,
57  CREDIT_CARD_TYPE,
58  NUM_FIELD_TYPE_GROUPS_FOR_METRICS
59};
60
61// First, translates |field_type| to the corresponding logical |group| from
62// |FieldTypeGroupForMetrics|.  Then, interpolates this with the given |metric|,
63// which should be in the range [0, |num_possible_metrics|).
64// Returns the interpolated index.
65//
66// The interpolation maps the pair (|group|, |metric|) to a single index, so
67// that all the indicies for a given group are adjacent.  In particular, with
68// the groups {AMBIGUOUS, NAME, ...} combining with the metrics {UNKNOWN, MATCH,
69// MISMATCH}, we create this set of mapped indices:
70// {
71//   AMBIGUOUS+UNKNOWN,
72//   AMBIGUOUS+MATCH,
73//   AMBIGUOUS+MISMATCH,
74//   NAME+UNKNOWN,
75//   NAME+MATCH,
76//   NAME+MISMATCH,
77//   ...
78// }.
79//
80// Clients must ensure that |field_type| is one of the types Chrome supports
81// natively, e.g. |field_type| must not be a billng address.
82int GetFieldTypeGroupMetric(const AutofillFieldType field_type,
83                            const int metric,
84                            const int num_possible_metrics) {
85  DCHECK_LT(metric, num_possible_metrics);
86
87  FieldTypeGroupForMetrics group;
88  switch (AutofillType(field_type).group()) {
89    case AutofillType::NO_GROUP:
90      group = AMBIGUOUS;
91      break;
92
93    case AutofillType::NAME:
94      group = NAME;
95      break;
96
97    case AutofillType::COMPANY:
98      group = COMPANY;
99      break;
100
101    case AutofillType::ADDRESS_HOME:
102      switch (field_type) {
103        case ADDRESS_HOME_LINE1:
104          group = ADDRESS_LINE_1;
105          break;
106        case ADDRESS_HOME_LINE2:
107          group = ADDRESS_LINE_2;
108          break;
109        case ADDRESS_HOME_CITY:
110          group = ADDRESS_CITY;
111          break;
112        case ADDRESS_HOME_STATE:
113          group = ADDRESS_STATE;
114          break;
115        case ADDRESS_HOME_ZIP:
116          group = ADDRESS_ZIP;
117          break;
118        case ADDRESS_HOME_COUNTRY:
119          group = ADDRESS_COUNTRY;
120          break;
121        default:
122          NOTREACHED();
123          group = AMBIGUOUS;
124      }
125      break;
126
127    case AutofillType::EMAIL:
128      group = EMAIL;
129      break;
130
131    case AutofillType::PHONE_HOME:
132      group = PHONE;
133      break;
134
135    case AutofillType::CREDIT_CARD:
136      switch (field_type) {
137        case ::autofill::CREDIT_CARD_NAME:
138          group = CREDIT_CARD_NAME;
139          break;
140        case ::autofill::CREDIT_CARD_NUMBER:
141          group = CREDIT_CARD_NUMBER;
142          break;
143        case ::autofill::CREDIT_CARD_TYPE:
144          group = CREDIT_CARD_TYPE;
145        default:
146          group = CREDIT_CARD_DATE;
147      }
148      break;
149
150    default:
151      NOTREACHED();
152      group = AMBIGUOUS;
153  }
154
155  // Interpolate the |metric| with the |group|, so that all metrics for a given
156  // |group| are adjacent.
157  return (group * num_possible_metrics) + metric;
158}
159
160// Returns the histogram prefix to use for reporting metrics for |dialog_type|.
161std::string GetPrefixForDialogType(autofill::DialogType dialog_type) {
162  switch (dialog_type) {
163    case autofill::DIALOG_TYPE_AUTOCHECKOUT:
164      return "Autocheckout";
165
166    case autofill::DIALOG_TYPE_REQUEST_AUTOCOMPLETE:
167      return "RequestAutocomplete";
168  }
169
170  NOTREACHED();
171  return "UnknownDialogType";
172}
173
174std::string WalletApiMetricToString(
175    AutofillMetrics::WalletApiCallMetric metric) {
176  switch (metric) {
177    case AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS:
178      return "AcceptLegalDocuments";
179    case AutofillMetrics::AUTHENTICATE_INSTRUMENT:
180      return "AuthenticateInstrument";
181    case AutofillMetrics::GET_FULL_WALLET:
182      return "GetFullWallet";
183    case AutofillMetrics::GET_WALLET_ITEMS:
184      return "GetWalletItems";
185    case AutofillMetrics::SAVE_ADDRESS:
186      return "SaveAddress";
187    case AutofillMetrics::SAVE_INSTRUMENT:
188      return "SaveInstrument";
189    case AutofillMetrics::SAVE_INSTRUMENT_AND_ADDRESS:
190      return "SaveInstrumentAndAddress";
191    case AutofillMetrics::SEND_STATUS:
192      return "SendStatus";
193    case AutofillMetrics::UPDATE_ADDRESS:
194      return "UpdateAddress";
195    case AutofillMetrics::UPDATE_INSTRUMENT:
196      return "UpdateInstrument";
197    case AutofillMetrics::UNKNOWN_API_CALL:
198      NOTREACHED();
199      return "UnknownApiCall";
200  }
201
202  NOTREACHED();
203  return "UnknownApiCall";
204}
205
206// A version of the UMA_HISTOGRAM_ENUMERATION macro that allows the |name|
207// to vary over the program's runtime.
208void LogUMAHistogramEnumeration(const std::string& name,
209                                int sample,
210                                int boundary_value) {
211  DCHECK_LT(sample, boundary_value);
212
213  // Note: This leaks memory, which is expected behavior.
214  base::HistogramBase* histogram =
215      base::LinearHistogram::FactoryGet(
216          name,
217          1,
218          boundary_value,
219          boundary_value + 1,
220          base::HistogramBase::kUmaTargetedHistogramFlag);
221  histogram->Add(sample);
222}
223
224// A version of the UMA_HISTOGRAM_TIMES macro that allows the |name|
225// to vary over the program's runtime.
226void LogUMAHistogramTimes(const std::string& name,
227                          const base::TimeDelta& duration) {
228  // Note: This leaks memory, which is expected behavior.
229  base::HistogramBase* histogram =
230      base::Histogram::FactoryTimeGet(
231          name,
232          base::TimeDelta::FromMilliseconds(1),
233          base::TimeDelta::FromSeconds(10),
234          50,
235          base::HistogramBase::kUmaTargetedHistogramFlag);
236  histogram->AddTime(duration);
237}
238
239// A version of the UMA_HISTOGRAM_LONG_TIMES macro that allows the |name|
240// to vary over the program's runtime.
241void LogUMAHistogramLongTimes(const std::string& name,
242                              const base::TimeDelta& duration) {
243  // Note: This leaks memory, which is expected behavior.
244  base::HistogramBase* histogram =
245      base::Histogram::FactoryTimeGet(
246          name,
247          base::TimeDelta::FromMilliseconds(1),
248          base::TimeDelta::FromHours(1),
249          50,
250          base::HistogramBase::kUmaTargetedHistogramFlag);
251  histogram->AddTime(duration);
252}
253
254// Logs a type quality metric.  The primary histogram name is constructed based
255// on |base_name| and |experiment_id|.  The field-specific histogram name also
256// factors in the |field_type|.  Logs a sample of |metric|, which should be in
257// the range [0, |num_possible_metrics|).
258void LogTypeQualityMetric(const std::string& base_name,
259                          const int metric,
260                          const int num_possible_metrics,
261                          const AutofillFieldType field_type,
262                          const std::string& experiment_id) {
263  DCHECK_LT(metric, num_possible_metrics);
264
265  std::string histogram_name = base_name;
266  if (!experiment_id.empty())
267    histogram_name += "_" + experiment_id;
268  LogUMAHistogramEnumeration(histogram_name, metric, num_possible_metrics);
269
270  std::string sub_histogram_name = base_name + ".ByFieldType";
271  if (!experiment_id.empty())
272    sub_histogram_name += "_" + experiment_id;
273  const int field_type_group_metric =
274      GetFieldTypeGroupMetric(field_type, metric, num_possible_metrics);
275  const int num_field_type_group_metrics =
276      num_possible_metrics * NUM_FIELD_TYPE_GROUPS_FOR_METRICS;
277  LogUMAHistogramEnumeration(sub_histogram_name,
278                             field_type_group_metric,
279                             num_field_type_group_metrics);
280}
281
282void LogServerExperimentId(const std::string& histogram_name,
283                           const std::string& experiment_id) {
284  ServerExperiment metric = UNKNOWN_EXPERIMENT;
285
286  const std::string default_experiment_name =
287      FormStructure(FormData(), std::string()).server_experiment_id();
288  if (experiment_id.empty())
289    metric = NO_EXPERIMENT;
290  else if (experiment_id == "ar06")
291    metric = ACCEPTANCE_RATIO_06;
292  else if (experiment_id == "ar1")
293    metric = ACCEPTANCE_RATIO_1;
294  else if (experiment_id == "ar2")
295    metric = ACCEPTANCE_RATIO_2;
296  else if (experiment_id == "ar4")
297    metric = ACCEPTANCE_RATIO_4;
298  else if (experiment_id == "ar05wlr15")
299    metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15;
300  else if (experiment_id == "ar05wlr25")
301    metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_25;
302  else if (experiment_id == "ar05wr15fs5")
303    metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15_MIN_FORM_SCORE_5;
304  else if (experiment_id == "tbar1")
305    metric = TOOLBAR_DATA_ONLY;
306  else if (experiment_id == "ar04wr3fs4")
307    metric = ACCEPTANCE_RATIO_04_WINNER_LEAD_RATIO_3_MIN_FORM_SCORE_4;
308  else if (experiment_id == default_experiment_name)
309    metric = NO_SERVER_RESPONSE;
310  else if (experiment_id == "fp05")
311    metric = PROBABILITY_PICKER_05;
312  else if (experiment_id == "fp025")
313    metric = PROBABILITY_PICKER_025;
314  else if (experiment_id == "fp05cc03")
315    metric = PROBABILITY_PICKER_025_CC_THRESHOLD_03;
316  else if (experiment_id == "fp05cco03")
317    metric = PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03;
318  else if (experiment_id == "fp05cco03cstd")
319    metric = PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03_WITH_FALLBACK;
320  else if (experiment_id == "fp05cc03e1")
321    metric = PROBABILITY_PICKER_05_CC_NAME_THRESHOLD_03_EXPERIMENT_1;
322
323  DCHECK_LT(metric, NUM_SERVER_EXPERIMENTS);
324  LogUMAHistogramEnumeration(histogram_name, metric, NUM_SERVER_EXPERIMENTS);
325}
326
327}  // namespace
328
329AutofillMetrics::AutofillMetrics() {
330}
331
332AutofillMetrics::~AutofillMetrics() {
333}
334
335void AutofillMetrics::LogAutocheckoutBubbleMetric(BubbleMetric metric) const {
336  DCHECK_LT(metric, NUM_BUBBLE_METRICS);
337
338  UMA_HISTOGRAM_ENUMERATION("Autocheckout.Bubble", metric, NUM_BUBBLE_METRICS);
339}
340
341void AutofillMetrics::LogAutocheckoutBuyFlowMetric(
342    AutocheckoutBuyFlowMetric metric) const {
343  DCHECK_LT(metric, NUM_AUTOCHECKOUT_BUY_FLOW_METRICS);
344
345  UMA_HISTOGRAM_ENUMERATION("Autocheckout.BuyFlow", metric,
346                            NUM_AUTOCHECKOUT_BUY_FLOW_METRICS);
347}
348
349void AutofillMetrics::LogCreditCardInfoBarMetric(InfoBarMetric metric) const {
350  DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
351
352  UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar", metric,
353                            NUM_INFO_BAR_METRICS);
354}
355
356void AutofillMetrics::LogDialogDismissalState(
357    autofill::DialogType dialog_type,
358    DialogDismissalState state) const {
359  std::string name = GetPrefixForDialogType(dialog_type) + ".DismissalState";
360  LogUMAHistogramEnumeration(name, state, NUM_DIALOG_DISMISSAL_STATES);
361}
362
363void AutofillMetrics::LogDialogInitialUserState(
364    autofill::DialogType dialog_type,
365    DialogInitialUserStateMetric user_type) const {
366  std::string name = GetPrefixForDialogType(dialog_type) + ".InitialUserState";
367  LogUMAHistogramEnumeration(
368      name, user_type, NUM_DIALOG_INITIAL_USER_STATE_METRICS);
369}
370
371void AutofillMetrics::LogDialogLatencyToShow(
372    autofill::DialogType dialog_type,
373    const base::TimeDelta& duration) const {
374  std::string name =
375      GetPrefixForDialogType(dialog_type) + ".UiLatencyToShow";
376  LogUMAHistogramTimes(name, duration);
377}
378
379void AutofillMetrics::LogDialogPopupEvent(autofill::DialogType dialog_type,
380                                          DialogPopupEvent event) const {
381  std::string name = GetPrefixForDialogType(dialog_type) + ".PopupInDialog";
382  LogUMAHistogramEnumeration(name, event, NUM_DIALOG_POPUP_EVENTS);
383}
384
385void AutofillMetrics::LogDialogSecurityMetric(
386    autofill::DialogType dialog_type,
387    DialogSecurityMetric metric) const {
388  std::string name = GetPrefixForDialogType(dialog_type) + ".Security";
389  LogUMAHistogramEnumeration(name, metric, NUM_DIALOG_SECURITY_METRICS);
390}
391
392void AutofillMetrics::LogDialogUiDuration(
393    const base::TimeDelta& duration,
394    autofill::DialogType dialog_type,
395    DialogDismissalAction dismissal_action) const {
396  std::string prefix = GetPrefixForDialogType(dialog_type);
397
398  std::string suffix;
399  switch (dismissal_action) {
400    case DIALOG_ACCEPTED:
401      suffix = "Submit";
402      break;
403
404    case DIALOG_CANCELED:
405      suffix = "Cancel";
406      break;
407  }
408
409  LogUMAHistogramLongTimes(prefix + ".UiDuration", duration);
410  LogUMAHistogramLongTimes(prefix + ".UiDuration." + suffix, duration);
411}
412
413void AutofillMetrics::LogDialogUiEvent(autofill::DialogType dialog_type,
414                                       DialogUiEvent event) const {
415  std::string name = GetPrefixForDialogType(dialog_type) + ".UiEvents";
416  LogUMAHistogramEnumeration(name, event, NUM_DIALOG_UI_EVENTS);
417}
418
419void AutofillMetrics::LogWalletErrorMetric(autofill::DialogType dialog_type,
420                                           WalletErrorMetric metric) const {
421  std::string name = GetPrefixForDialogType(dialog_type) + ".WalletErrors";
422  LogUMAHistogramEnumeration(name, metric, NUM_WALLET_ERROR_METRICS);
423}
424
425void AutofillMetrics::LogWalletApiCallDuration(
426    WalletApiCallMetric metric,
427    const base::TimeDelta& duration) const {
428  LogUMAHistogramTimes("Wallet.ApiCallDuration." +
429                       WalletApiMetricToString(metric), duration);
430}
431
432void AutofillMetrics::LogWalletRequiredActionMetric(
433      autofill::DialogType dialog_type,
434      WalletRequiredActionMetric required_action) const {
435  std::string name =
436      GetPrefixForDialogType(dialog_type) + ".WalletRequiredActions";
437  LogUMAHistogramEnumeration(
438      name, required_action, NUM_WALLET_REQUIRED_ACTIONS);
439}
440
441void AutofillMetrics::LogAutocheckoutDuration(
442    const base::TimeDelta& duration,
443    AutocheckoutCompletionStatus status) const {
444  std::string suffix;
445  switch (status) {
446    case AUTOCHECKOUT_CANCELLED:
447      suffix = "Cancelled";
448      break;
449
450    case AUTOCHECKOUT_FAILED:
451      suffix = "Failed";
452      break;
453
454    case AUTOCHECKOUT_SUCCEEDED:
455      suffix = "Succeeded";
456      break;
457  }
458
459  LogUMAHistogramLongTimes("Autocheckout.FlowDuration", duration);
460  LogUMAHistogramLongTimes("Autocheckout.FlowDuration." + suffix, duration);
461}
462
463void AutofillMetrics::LogAutocheckoutWhitelistDownloadDuration(
464    const base::TimeDelta& duration,
465    AutocheckoutWhitelistDownloadStatus status) const {
466  std::string suffix;
467  switch (status) {
468    case AUTOCHECKOUT_WHITELIST_DOWNLOAD_FAILED:
469      suffix = "Failed";
470      break;
471
472    case AUTOCHECKOUT_WHITELIST_DOWNLOAD_SUCCEEDED:
473      suffix = "Succeeded";
474      break;
475  }
476
477  LogUMAHistogramTimes("Autocheckout.WhitelistDownloadDuration", duration);
478  LogUMAHistogramTimes(
479      "Autocheckout.WhitelistDownloadDuration." + suffix, duration);
480}
481
482void AutofillMetrics::LogDeveloperEngagementMetric(
483    DeveloperEngagementMetric metric) const {
484  DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS);
485
486  UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric,
487                            NUM_DEVELOPER_ENGAGEMENT_METRICS);
488}
489
490void AutofillMetrics::LogHeuristicTypePrediction(
491    FieldTypeQualityMetric metric,
492    AutofillFieldType field_type,
493    const std::string& experiment_id) const {
494  LogTypeQualityMetric("Autofill.Quality.HeuristicType",
495                       metric, NUM_FIELD_TYPE_QUALITY_METRICS,
496                       field_type, experiment_id);
497}
498
499void AutofillMetrics::LogOverallTypePrediction(
500    FieldTypeQualityMetric metric,
501    AutofillFieldType field_type,
502    const std::string& experiment_id) const {
503  LogTypeQualityMetric("Autofill.Quality.PredictedType",
504                       metric, NUM_FIELD_TYPE_QUALITY_METRICS,
505                       field_type, experiment_id);
506}
507
508void AutofillMetrics::LogServerTypePrediction(
509    FieldTypeQualityMetric metric,
510    AutofillFieldType field_type,
511    const std::string& experiment_id) const {
512  LogTypeQualityMetric("Autofill.Quality.ServerType",
513                       metric, NUM_FIELD_TYPE_QUALITY_METRICS,
514                       field_type, experiment_id);
515}
516
517void AutofillMetrics::LogQualityMetric(QualityMetric metric,
518                                       const std::string& experiment_id) const {
519  DCHECK_LT(metric, NUM_QUALITY_METRICS);
520
521  std::string histogram_name = "Autofill.Quality";
522  if (!experiment_id.empty())
523    histogram_name += "_" + experiment_id;
524
525  LogUMAHistogramEnumeration(histogram_name, metric, NUM_QUALITY_METRICS);
526}
527
528void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) const {
529  DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS);
530
531  UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric,
532                            NUM_SERVER_QUERY_METRICS);
533}
534
535void AutofillMetrics::LogUserHappinessMetric(UserHappinessMetric metric) const {
536  DCHECK_LT(metric, NUM_USER_HAPPINESS_METRICS);
537
538  UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness", metric,
539                            NUM_USER_HAPPINESS_METRICS);
540}
541
542void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill(
543    const base::TimeDelta& duration) const {
544  UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithAutofill",
545                             duration,
546                             base::TimeDelta::FromMilliseconds(100),
547                             base::TimeDelta::FromMinutes(10),
548                             50);
549}
550
551void AutofillMetrics::LogFormFillDurationFromLoadWithoutAutofill(
552    const base::TimeDelta& duration) const {
553  UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithoutAutofill",
554                             duration,
555                             base::TimeDelta::FromMilliseconds(100),
556                             base::TimeDelta::FromMinutes(10),
557                             50);
558}
559
560void AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill(
561    const base::TimeDelta& duration) const {
562  UMA_HISTOGRAM_CUSTOM_TIMES(
563      "Autofill.FillDuration.FromInteraction.WithAutofill",
564      duration,
565      base::TimeDelta::FromMilliseconds(100),
566      base::TimeDelta::FromMinutes(10),
567      50);
568}
569
570void AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill(
571    const base::TimeDelta& duration) const {
572  UMA_HISTOGRAM_CUSTOM_TIMES(
573       "Autofill.FillDuration.FromInteraction.WithoutAutofill",
574       duration,
575       base::TimeDelta::FromMilliseconds(100),
576       base::TimeDelta::FromMinutes(10),
577       50);
578}
579
580void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled) const {
581  UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled);
582}
583
584void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(bool enabled) const {
585  UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.PageLoad", enabled);
586}
587
588void AutofillMetrics::LogStoredProfileCount(size_t num_profiles) const {
589  UMA_HISTOGRAM_COUNTS("Autofill.StoredProfileCount", num_profiles);
590}
591
592void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) const {
593  UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions);
594}
595
596void AutofillMetrics::LogServerExperimentIdForQuery(
597    const std::string& experiment_id) const {
598  LogServerExperimentId("Autofill.ServerExperimentId.Query", experiment_id);
599}
600
601void AutofillMetrics::LogServerExperimentIdForUpload(
602    const std::string& experiment_id) const {
603  LogServerExperimentId("Autofill.ServerExperimentId.Upload", experiment_id);
604}
605
606}  // namespace autofill
607