autofill_metrics.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
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 ServerFieldType 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 ::autofill::NO_GROUP:
90      group = AMBIGUOUS;
91      break;
92
93    case ::autofill::NAME:
94      group = NAME;
95      break;
96
97    case ::autofill::COMPANY:
98      group = COMPANY;
99      break;
100
101    case ::autofill::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 ::autofill::EMAIL:
128      group = EMAIL;
129      break;
130
131    case ::autofill::PHONE_HOME:
132      group = PHONE;
133      break;
134
135    case ::autofill::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          break;
146        default:
147          group = CREDIT_CARD_DATE;
148      }
149      break;
150
151    default:
152      NOTREACHED();
153      group = AMBIGUOUS;
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// Returns the histogram prefix to use for reporting metrics for |dialog_type|.
162std::string GetPrefixForDialogType(autofill::DialogType dialog_type) {
163  switch (dialog_type) {
164    case autofill::DIALOG_TYPE_AUTOCHECKOUT:
165      return "Autocheckout";
166
167    case autofill::DIALOG_TYPE_REQUEST_AUTOCOMPLETE:
168      return "RequestAutocomplete";
169  }
170
171  NOTREACHED();
172  return "UnknownDialogType";
173}
174
175std::string WalletApiMetricToString(
176    AutofillMetrics::WalletApiCallMetric metric) {
177  switch (metric) {
178    case AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS:
179      return "AcceptLegalDocuments";
180    case AutofillMetrics::AUTHENTICATE_INSTRUMENT:
181      return "AuthenticateInstrument";
182    case AutofillMetrics::GET_FULL_WALLET:
183      return "GetFullWallet";
184    case AutofillMetrics::GET_WALLET_ITEMS:
185      return "GetWalletItems";
186    case AutofillMetrics::SAVE_TO_WALLET:
187      return "SaveToWallet";
188    case AutofillMetrics::SEND_STATUS:
189      return "SendStatus";
190    case AutofillMetrics::UNKNOWN_API_CALL:
191      NOTREACHED();
192      return "UnknownApiCall";
193  }
194
195  NOTREACHED();
196  return "UnknownApiCall";
197}
198
199// A version of the UMA_HISTOGRAM_ENUMERATION macro that allows the |name|
200// to vary over the program's runtime.
201void LogUMAHistogramEnumeration(const std::string& name,
202                                int sample,
203                                int boundary_value) {
204  DCHECK_LT(sample, boundary_value);
205
206  // Note: This leaks memory, which is expected behavior.
207  base::HistogramBase* histogram =
208      base::LinearHistogram::FactoryGet(
209          name,
210          1,
211          boundary_value,
212          boundary_value + 1,
213          base::HistogramBase::kUmaTargetedHistogramFlag);
214  histogram->Add(sample);
215}
216
217// A version of the UMA_HISTOGRAM_TIMES macro that allows the |name|
218// to vary over the program's runtime.
219void LogUMAHistogramTimes(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::FromSeconds(10),
227          50,
228          base::HistogramBase::kUmaTargetedHistogramFlag);
229  histogram->AddTime(duration);
230}
231
232// A version of the UMA_HISTOGRAM_LONG_TIMES macro that allows the |name|
233// to vary over the program's runtime.
234void LogUMAHistogramLongTimes(const std::string& name,
235                              const base::TimeDelta& duration) {
236  // Note: This leaks memory, which is expected behavior.
237  base::HistogramBase* histogram =
238      base::Histogram::FactoryTimeGet(
239          name,
240          base::TimeDelta::FromMilliseconds(1),
241          base::TimeDelta::FromHours(1),
242          50,
243          base::HistogramBase::kUmaTargetedHistogramFlag);
244  histogram->AddTime(duration);
245}
246
247// Logs a type quality metric.  The primary histogram name is constructed based
248// on |base_name| and |experiment_id|.  The field-specific histogram name also
249// factors in the |field_type|.  Logs a sample of |metric|, which should be in
250// the range [0, |num_possible_metrics|).
251void LogTypeQualityMetric(const std::string& base_name,
252                          const int metric,
253                          const int num_possible_metrics,
254                          const ServerFieldType field_type,
255                          const std::string& experiment_id) {
256  DCHECK_LT(metric, num_possible_metrics);
257
258  std::string histogram_name = base_name;
259  if (!experiment_id.empty())
260    histogram_name += "_" + experiment_id;
261  LogUMAHistogramEnumeration(histogram_name, metric, num_possible_metrics);
262
263  std::string sub_histogram_name = base_name + ".ByFieldType";
264  if (!experiment_id.empty())
265    sub_histogram_name += "_" + experiment_id;
266  const int field_type_group_metric =
267      GetFieldTypeGroupMetric(field_type, metric, num_possible_metrics);
268  const int num_field_type_group_metrics =
269      num_possible_metrics * NUM_FIELD_TYPE_GROUPS_FOR_METRICS;
270  LogUMAHistogramEnumeration(sub_histogram_name,
271                             field_type_group_metric,
272                             num_field_type_group_metrics);
273}
274
275void LogServerExperimentId(const std::string& histogram_name,
276                           const std::string& experiment_id) {
277  ServerExperiment metric = UNKNOWN_EXPERIMENT;
278
279  const std::string default_experiment_name =
280      FormStructure(FormData(), std::string()).server_experiment_id();
281  if (experiment_id.empty())
282    metric = NO_EXPERIMENT;
283  else if (experiment_id == "ar06")
284    metric = ACCEPTANCE_RATIO_06;
285  else if (experiment_id == "ar1")
286    metric = ACCEPTANCE_RATIO_1;
287  else if (experiment_id == "ar2")
288    metric = ACCEPTANCE_RATIO_2;
289  else if (experiment_id == "ar4")
290    metric = ACCEPTANCE_RATIO_4;
291  else if (experiment_id == "ar05wlr15")
292    metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15;
293  else if (experiment_id == "ar05wlr25")
294    metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_25;
295  else if (experiment_id == "ar05wr15fs5")
296    metric = ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15_MIN_FORM_SCORE_5;
297  else if (experiment_id == "tbar1")
298    metric = TOOLBAR_DATA_ONLY;
299  else if (experiment_id == "ar04wr3fs4")
300    metric = ACCEPTANCE_RATIO_04_WINNER_LEAD_RATIO_3_MIN_FORM_SCORE_4;
301  else if (experiment_id == default_experiment_name)
302    metric = NO_SERVER_RESPONSE;
303  else if (experiment_id == "fp05")
304    metric = PROBABILITY_PICKER_05;
305  else if (experiment_id == "fp025")
306    metric = PROBABILITY_PICKER_025;
307  else if (experiment_id == "fp05cc03")
308    metric = PROBABILITY_PICKER_025_CC_THRESHOLD_03;
309  else if (experiment_id == "fp05cco03")
310    metric = PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03;
311  else if (experiment_id == "fp05cco03cstd")
312    metric = PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03_WITH_FALLBACK;
313  else if (experiment_id == "fp05cc03e1")
314    metric = PROBABILITY_PICKER_05_CC_NAME_THRESHOLD_03_EXPERIMENT_1;
315
316  DCHECK_LT(metric, NUM_SERVER_EXPERIMENTS);
317  LogUMAHistogramEnumeration(histogram_name, metric, NUM_SERVER_EXPERIMENTS);
318}
319
320}  // namespace
321
322AutofillMetrics::AutofillMetrics() {
323}
324
325AutofillMetrics::~AutofillMetrics() {
326}
327
328void AutofillMetrics::LogAutocheckoutBubbleMetric(BubbleMetric metric) const {
329  DCHECK_LT(metric, NUM_BUBBLE_METRICS);
330
331  UMA_HISTOGRAM_ENUMERATION("Autocheckout.Bubble", metric, NUM_BUBBLE_METRICS);
332}
333
334void AutofillMetrics::LogAutocheckoutBuyFlowMetric(
335    AutocheckoutBuyFlowMetric metric) const {
336  DCHECK_LT(metric, NUM_AUTOCHECKOUT_BUY_FLOW_METRICS);
337
338  UMA_HISTOGRAM_ENUMERATION("Autocheckout.BuyFlow", metric,
339                            NUM_AUTOCHECKOUT_BUY_FLOW_METRICS);
340}
341
342void AutofillMetrics::LogCreditCardInfoBarMetric(InfoBarMetric metric) const {
343  DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
344
345  UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar", metric,
346                            NUM_INFO_BAR_METRICS);
347}
348
349void AutofillMetrics::LogDialogDismissalState(
350    autofill::DialogType dialog_type,
351    DialogDismissalState state) const {
352  std::string name = GetPrefixForDialogType(dialog_type) + ".DismissalState";
353  LogUMAHistogramEnumeration(name, state, NUM_DIALOG_DISMISSAL_STATES);
354}
355
356void AutofillMetrics::LogDialogInitialUserState(
357    autofill::DialogType dialog_type,
358    DialogInitialUserStateMetric user_type) const {
359  std::string name = GetPrefixForDialogType(dialog_type) + ".InitialUserState";
360  LogUMAHistogramEnumeration(
361      name, user_type, NUM_DIALOG_INITIAL_USER_STATE_METRICS);
362}
363
364void AutofillMetrics::LogDialogLatencyToShow(
365    autofill::DialogType dialog_type,
366    const base::TimeDelta& duration) const {
367  std::string name =
368      GetPrefixForDialogType(dialog_type) + ".UiLatencyToShow";
369  LogUMAHistogramTimes(name, duration);
370}
371
372void AutofillMetrics::LogDialogPopupEvent(autofill::DialogType dialog_type,
373                                          DialogPopupEvent event) const {
374  std::string name = GetPrefixForDialogType(dialog_type) + ".PopupInDialog";
375  LogUMAHistogramEnumeration(name, event, NUM_DIALOG_POPUP_EVENTS);
376}
377
378void AutofillMetrics::LogDialogSecurityMetric(
379    autofill::DialogType dialog_type,
380    DialogSecurityMetric metric) const {
381  std::string name = GetPrefixForDialogType(dialog_type) + ".Security";
382  LogUMAHistogramEnumeration(name, metric, NUM_DIALOG_SECURITY_METRICS);
383}
384
385void AutofillMetrics::LogDialogUiDuration(
386    const base::TimeDelta& duration,
387    autofill::DialogType dialog_type,
388    DialogDismissalAction dismissal_action) const {
389  std::string prefix = GetPrefixForDialogType(dialog_type);
390
391  std::string suffix;
392  switch (dismissal_action) {
393    case DIALOG_ACCEPTED:
394      suffix = "Submit";
395      break;
396
397    case DIALOG_CANCELED:
398      suffix = "Cancel";
399      break;
400  }
401
402  LogUMAHistogramLongTimes(prefix + ".UiDuration", duration);
403  LogUMAHistogramLongTimes(prefix + ".UiDuration." + suffix, duration);
404}
405
406void AutofillMetrics::LogDialogUiEvent(autofill::DialogType dialog_type,
407                                       DialogUiEvent event) const {
408  std::string name = GetPrefixForDialogType(dialog_type) + ".UiEvents";
409  LogUMAHistogramEnumeration(name, event, NUM_DIALOG_UI_EVENTS);
410}
411
412void AutofillMetrics::LogWalletErrorMetric(autofill::DialogType dialog_type,
413                                           WalletErrorMetric metric) const {
414  std::string name = GetPrefixForDialogType(dialog_type) + ".WalletErrors";
415  LogUMAHistogramEnumeration(name, metric, NUM_WALLET_ERROR_METRICS);
416}
417
418void AutofillMetrics::LogWalletApiCallDuration(
419    WalletApiCallMetric metric,
420    const base::TimeDelta& duration) const {
421  LogUMAHistogramTimes("Wallet.ApiCallDuration." +
422                       WalletApiMetricToString(metric), duration);
423}
424
425void AutofillMetrics::LogWalletRequiredActionMetric(
426      autofill::DialogType dialog_type,
427      WalletRequiredActionMetric required_action) const {
428  std::string name =
429      GetPrefixForDialogType(dialog_type) + ".WalletRequiredActions";
430  LogUMAHistogramEnumeration(
431      name, required_action, NUM_WALLET_REQUIRED_ACTIONS);
432}
433
434void AutofillMetrics::LogAutocheckoutDuration(
435    const base::TimeDelta& duration,
436    AutocheckoutCompletionStatus status) const {
437  std::string suffix;
438  switch (status) {
439    case AUTOCHECKOUT_CANCELLED:
440      suffix = "Cancelled";
441      break;
442
443    case AUTOCHECKOUT_FAILED:
444      suffix = "Failed";
445      break;
446
447    case AUTOCHECKOUT_SUCCEEDED:
448      suffix = "Succeeded";
449      break;
450  }
451
452  LogUMAHistogramLongTimes("Autocheckout.FlowDuration", duration);
453  LogUMAHistogramLongTimes("Autocheckout.FlowDuration." + suffix, duration);
454}
455
456void AutofillMetrics::LogAutocheckoutWhitelistDownloadDuration(
457    const base::TimeDelta& duration,
458    AutocheckoutWhitelistDownloadStatus status) const {
459  std::string suffix;
460  switch (status) {
461    case AUTOCHECKOUT_WHITELIST_DOWNLOAD_FAILED:
462      suffix = "Failed";
463      break;
464
465    case AUTOCHECKOUT_WHITELIST_DOWNLOAD_SUCCEEDED:
466      suffix = "Succeeded";
467      break;
468  }
469
470  LogUMAHistogramTimes("Autocheckout.WhitelistDownloadDuration", duration);
471  LogUMAHistogramTimes(
472      "Autocheckout.WhitelistDownloadDuration." + suffix, duration);
473}
474
475void AutofillMetrics::LogDeveloperEngagementMetric(
476    DeveloperEngagementMetric metric) const {
477  DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS);
478
479  UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric,
480                            NUM_DEVELOPER_ENGAGEMENT_METRICS);
481}
482
483void AutofillMetrics::LogHeuristicTypePrediction(
484    FieldTypeQualityMetric metric,
485    ServerFieldType field_type,
486    const std::string& experiment_id) const {
487  LogTypeQualityMetric("Autofill.Quality.HeuristicType",
488                       metric, NUM_FIELD_TYPE_QUALITY_METRICS,
489                       field_type, experiment_id);
490}
491
492void AutofillMetrics::LogOverallTypePrediction(
493    FieldTypeQualityMetric metric,
494    ServerFieldType field_type,
495    const std::string& experiment_id) const {
496  LogTypeQualityMetric("Autofill.Quality.PredictedType",
497                       metric, NUM_FIELD_TYPE_QUALITY_METRICS,
498                       field_type, experiment_id);
499}
500
501void AutofillMetrics::LogServerTypePrediction(
502    FieldTypeQualityMetric metric,
503    ServerFieldType field_type,
504    const std::string& experiment_id) const {
505  LogTypeQualityMetric("Autofill.Quality.ServerType",
506                       metric, NUM_FIELD_TYPE_QUALITY_METRICS,
507                       field_type, experiment_id);
508}
509
510void AutofillMetrics::LogQualityMetric(QualityMetric metric,
511                                       const std::string& experiment_id) const {
512  DCHECK_LT(metric, NUM_QUALITY_METRICS);
513
514  std::string histogram_name = "Autofill.Quality";
515  if (!experiment_id.empty())
516    histogram_name += "_" + experiment_id;
517
518  LogUMAHistogramEnumeration(histogram_name, metric, NUM_QUALITY_METRICS);
519}
520
521void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) const {
522  DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS);
523
524  UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric,
525                            NUM_SERVER_QUERY_METRICS);
526}
527
528void AutofillMetrics::LogUserHappinessMetric(UserHappinessMetric metric) const {
529  DCHECK_LT(metric, NUM_USER_HAPPINESS_METRICS);
530
531  UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness", metric,
532                            NUM_USER_HAPPINESS_METRICS);
533}
534
535void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill(
536    const base::TimeDelta& duration) const {
537  UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithAutofill",
538                             duration,
539                             base::TimeDelta::FromMilliseconds(100),
540                             base::TimeDelta::FromMinutes(10),
541                             50);
542}
543
544void AutofillMetrics::LogFormFillDurationFromLoadWithoutAutofill(
545    const base::TimeDelta& duration) const {
546  UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithoutAutofill",
547                             duration,
548                             base::TimeDelta::FromMilliseconds(100),
549                             base::TimeDelta::FromMinutes(10),
550                             50);
551}
552
553void AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill(
554    const base::TimeDelta& duration) const {
555  UMA_HISTOGRAM_CUSTOM_TIMES(
556      "Autofill.FillDuration.FromInteraction.WithAutofill",
557      duration,
558      base::TimeDelta::FromMilliseconds(100),
559      base::TimeDelta::FromMinutes(10),
560      50);
561}
562
563void AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill(
564    const base::TimeDelta& duration) const {
565  UMA_HISTOGRAM_CUSTOM_TIMES(
566       "Autofill.FillDuration.FromInteraction.WithoutAutofill",
567       duration,
568       base::TimeDelta::FromMilliseconds(100),
569       base::TimeDelta::FromMinutes(10),
570       50);
571}
572
573void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled) const {
574  UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled);
575}
576
577void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(bool enabled) const {
578  UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.PageLoad", enabled);
579}
580
581void AutofillMetrics::LogStoredProfileCount(size_t num_profiles) const {
582  UMA_HISTOGRAM_COUNTS("Autofill.StoredProfileCount", num_profiles);
583}
584
585void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) const {
586  UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions);
587}
588
589void AutofillMetrics::LogServerExperimentIdForQuery(
590    const std::string& experiment_id) const {
591  LogServerExperimentId("Autofill.ServerExperimentId.Query", experiment_id);
592}
593
594void AutofillMetrics::LogServerExperimentIdForUpload(
595    const std::string& experiment_id) const {
596  LogServerExperimentId("Autofill.ServerExperimentId.Upload", experiment_id);
597}
598
599}  // namespace autofill
600