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 // Server experiments we support.
20 enum ServerExperiment {
21 NO_EXPERIMENT = 0,
22 UNKNOWN_EXPERIMENT,
23 ACCEPTANCE_RATIO_06,
24 ACCEPTANCE_RATIO_1,
25 ACCEPTANCE_RATIO_2,
26 ACCEPTANCE_RATIO_4,
27 ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15,
28 ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_25,
29 ACCEPTANCE_RATIO_05_WINNER_LEAD_RATIO_15_MIN_FORM_SCORE_5,
30 TOOLBAR_DATA_ONLY,
31 ACCEPTANCE_RATIO_04_WINNER_LEAD_RATIO_3_MIN_FORM_SCORE_4,
32 NO_SERVER_RESPONSE,
33 PROBABILITY_PICKER_05,
34 PROBABILITY_PICKER_025,
35 PROBABILITY_PICKER_025_CC_THRESHOLD_03,
36 PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03,
37 PROBABILITY_PICKER_025_CONTEXTUAL_CC_THRESHOLD_03_WITH_FALLBACK,
38 PROBABILITY_PICKER_05_CC_NAME_THRESHOLD_03_EXPERIMENT_1,
39 NUM_SERVER_EXPERIMENTS
40 };
41
42 enum FieldTypeGroupForMetrics {
43 AMBIGUOUS = 0,
44 NAME,
45 COMPANY,
46 ADDRESS_LINE_1,
47 ADDRESS_LINE_2,
48 ADDRESS_CITY,
49 ADDRESS_STATE,
50 ADDRESS_ZIP,
51 ADDRESS_COUNTRY,
52 PHONE,
53 FAX, // Deprecated.
54 EMAIL,
55 CREDIT_CARD_NAME,
56 CREDIT_CARD_NUMBER,
57 CREDIT_CARD_DATE,
58 CREDIT_CARD_TYPE,
59 PASSWORD,
60 NUM_FIELD_TYPE_GROUPS_FOR_METRICS
61 };
62
63 // First, translates |field_type| to the corresponding logical |group| from
64 // |FieldTypeGroupForMetrics|. Then, interpolates this with the given |metric|,
65 // which should be in the range [0, |num_possible_metrics|).
66 // Returns the interpolated index.
67 //
68 // The interpolation maps the pair (|group|, |metric|) to a single index, so
69 // that all the indicies for a given group are adjacent. In particular, with
70 // the groups {AMBIGUOUS, NAME, ...} combining with the metrics {UNKNOWN, MATCH,
71 // MISMATCH}, we create this set of mapped indices:
72 // {
73 // AMBIGUOUS+UNKNOWN,
74 // AMBIGUOUS+MATCH,
75 // AMBIGUOUS+MISMATCH,
76 // NAME+UNKNOWN,
77 // NAME+MATCH,
78 // NAME+MISMATCH,
79 // ...
80 // }.
81 //
82 // Clients must ensure that |field_type| is one of the types Chrome supports
83 // natively, e.g. |field_type| must not be a billng address.
GetFieldTypeGroupMetric(const ServerFieldType field_type,const int metric,const int num_possible_metrics)84 int GetFieldTypeGroupMetric(const ServerFieldType field_type,
85 const int metric,
86 const int num_possible_metrics) {
87 DCHECK_LT(metric, num_possible_metrics);
88
89 FieldTypeGroupForMetrics group = AMBIGUOUS;
90 switch (AutofillType(field_type).group()) {
91 case ::autofill::NO_GROUP:
92 group = AMBIGUOUS;
93 break;
94
95 case ::autofill::NAME:
96 case ::autofill::NAME_BILLING:
97 group = NAME;
98 break;
99
100 case ::autofill::COMPANY:
101 group = COMPANY;
102 break;
103
104 case ::autofill::ADDRESS_HOME:
105 case ::autofill::ADDRESS_BILLING:
106 switch (AutofillType(field_type).GetStorableType()) {
107 case ADDRESS_HOME_LINE1:
108 group = ADDRESS_LINE_1;
109 break;
110 case ADDRESS_HOME_LINE2:
111 group = ADDRESS_LINE_2;
112 break;
113 case ADDRESS_HOME_CITY:
114 group = ADDRESS_CITY;
115 break;
116 case ADDRESS_HOME_STATE:
117 group = ADDRESS_STATE;
118 break;
119 case ADDRESS_HOME_ZIP:
120 group = ADDRESS_ZIP;
121 break;
122 case ADDRESS_HOME_COUNTRY:
123 group = ADDRESS_COUNTRY;
124 break;
125 default:
126 NOTREACHED();
127 group = AMBIGUOUS;
128 break;
129 }
130 break;
131
132 case ::autofill::EMAIL:
133 group = EMAIL;
134 break;
135
136 case ::autofill::PHONE_HOME:
137 case ::autofill::PHONE_BILLING:
138 group = PHONE;
139 break;
140
141 case ::autofill::CREDIT_CARD:
142 switch (field_type) {
143 case ::autofill::CREDIT_CARD_NAME:
144 group = CREDIT_CARD_NAME;
145 break;
146 case ::autofill::CREDIT_CARD_NUMBER:
147 group = CREDIT_CARD_NUMBER;
148 break;
149 case ::autofill::CREDIT_CARD_TYPE:
150 group = CREDIT_CARD_TYPE;
151 break;
152 case ::autofill::CREDIT_CARD_EXP_MONTH:
153 case ::autofill::CREDIT_CARD_EXP_2_DIGIT_YEAR:
154 case ::autofill::CREDIT_CARD_EXP_4_DIGIT_YEAR:
155 case ::autofill::CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR:
156 case ::autofill::CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR:
157 group = CREDIT_CARD_DATE;
158 break;
159 default:
160 NOTREACHED();
161 group = AMBIGUOUS;
162 break;
163 }
164 break;
165
166 case ::autofill::PASSWORD_FIELD:
167 group = PASSWORD;
168 break;
169 }
170
171 // Interpolate the |metric| with the |group|, so that all metrics for a given
172 // |group| are adjacent.
173 return (group * num_possible_metrics) + metric;
174 }
175
WalletApiMetricToString(AutofillMetrics::WalletApiCallMetric metric)176 std::string WalletApiMetricToString(
177 AutofillMetrics::WalletApiCallMetric metric) {
178 switch (metric) {
179 case AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS:
180 return "AcceptLegalDocuments";
181 case AutofillMetrics::AUTHENTICATE_INSTRUMENT:
182 return "AuthenticateInstrument";
183 case AutofillMetrics::GET_FULL_WALLET:
184 return "GetFullWallet";
185 case AutofillMetrics::GET_WALLET_ITEMS:
186 return "GetWalletItems";
187 case AutofillMetrics::SAVE_TO_WALLET:
188 return "SaveToWallet";
189 case AutofillMetrics::UNKNOWN_API_CALL:
190 case AutofillMetrics::NUM_WALLET_API_CALLS:
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.
LogUMAHistogramEnumeration(const std::string & name,int sample,int boundary_value)201 void 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.
LogUMAHistogramTimes(const std::string & name,const base::TimeDelta & duration)219 void 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.
LogUMAHistogramLongTimes(const std::string & name,const base::TimeDelta & duration)234 void 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|).
LogTypeQualityMetric(const std::string & base_name,const int metric,const int num_possible_metrics,const ServerFieldType field_type,const std::string & experiment_id)251 void 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
LogServerExperimentId(const std::string & histogram_name,const std::string & experiment_id)275 void 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()).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
AutofillMetrics()322 AutofillMetrics::AutofillMetrics() {
323 }
324
~AutofillMetrics()325 AutofillMetrics::~AutofillMetrics() {
326 }
327
LogCreditCardInfoBarMetric(InfoBarMetric metric) const328 void AutofillMetrics::LogCreditCardInfoBarMetric(InfoBarMetric metric) const {
329 DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
330
331 UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar", metric,
332 NUM_INFO_BAR_METRICS);
333 }
334
LogDialogDismissalState(DialogDismissalState state) const335 void AutofillMetrics::LogDialogDismissalState(
336 DialogDismissalState state) const {
337 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.DismissalState",
338 state, NUM_DIALOG_DISMISSAL_STATES);
339 }
340
LogDialogInitialUserState(DialogInitialUserStateMetric user_type) const341 void AutofillMetrics::LogDialogInitialUserState(
342 DialogInitialUserStateMetric user_type) const {
343 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.InitialUserState",
344 user_type, NUM_DIALOG_INITIAL_USER_STATE_METRICS);
345 }
346
LogDialogLatencyToShow(const base::TimeDelta & duration) const347 void AutofillMetrics::LogDialogLatencyToShow(
348 const base::TimeDelta& duration) const {
349 LogUMAHistogramTimes("RequestAutocomplete.UiLatencyToShow", duration);
350 }
351
LogDialogPopupEvent(DialogPopupEvent event) const352 void AutofillMetrics::LogDialogPopupEvent(DialogPopupEvent event) const {
353 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.PopupInDialog",
354 event, NUM_DIALOG_POPUP_EVENTS);
355 }
356
LogDialogSecurityMetric(DialogSecurityMetric metric) const357 void AutofillMetrics::LogDialogSecurityMetric(
358 DialogSecurityMetric metric) const {
359 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.Security",
360 metric, NUM_DIALOG_SECURITY_METRICS);
361 }
362
LogDialogUiDuration(const base::TimeDelta & duration,DialogDismissalAction dismissal_action) const363 void AutofillMetrics::LogDialogUiDuration(
364 const base::TimeDelta& duration,
365 DialogDismissalAction dismissal_action) const {
366 std::string suffix;
367 switch (dismissal_action) {
368 case DIALOG_ACCEPTED:
369 suffix = "Submit";
370 break;
371
372 case DIALOG_CANCELED:
373 suffix = "Cancel";
374 break;
375 }
376
377 LogUMAHistogramLongTimes("RequestAutocomplete.UiDuration", duration);
378 LogUMAHistogramLongTimes("RequestAutocomplete.UiDuration." + suffix,
379 duration);
380 }
381
LogDialogUiEvent(DialogUiEvent event) const382 void AutofillMetrics::LogDialogUiEvent(DialogUiEvent event) const {
383 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.UiEvents", event,
384 NUM_DIALOG_UI_EVENTS);
385 }
386
LogWalletErrorMetric(WalletErrorMetric metric) const387 void AutofillMetrics::LogWalletErrorMetric(WalletErrorMetric metric) const {
388 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.WalletErrors", metric,
389 NUM_WALLET_ERROR_METRICS);
390 }
391
LogWalletApiCallDuration(WalletApiCallMetric metric,const base::TimeDelta & duration) const392 void AutofillMetrics::LogWalletApiCallDuration(
393 WalletApiCallMetric metric,
394 const base::TimeDelta& duration) const {
395 LogUMAHistogramTimes("Wallet.ApiCallDuration." +
396 WalletApiMetricToString(metric), duration);
397 }
398
LogWalletMalformedResponseMetric(WalletApiCallMetric metric) const399 void AutofillMetrics::LogWalletMalformedResponseMetric(
400 WalletApiCallMetric metric) const {
401 UMA_HISTOGRAM_ENUMERATION("Wallet.MalformedResponse", metric,
402 NUM_WALLET_API_CALLS);
403 }
404
LogWalletRequiredActionMetric(WalletRequiredActionMetric required_action) const405 void AutofillMetrics::LogWalletRequiredActionMetric(
406 WalletRequiredActionMetric required_action) const {
407 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.WalletRequiredActions",
408 required_action, NUM_WALLET_REQUIRED_ACTIONS);
409 }
410
LogWalletResponseCode(int response_code) const411 void AutofillMetrics::LogWalletResponseCode(int response_code) const {
412 UMA_HISTOGRAM_SPARSE_SLOWLY("Wallet.ResponseCode", response_code);
413 }
414
LogDeveloperEngagementMetric(DeveloperEngagementMetric metric) const415 void AutofillMetrics::LogDeveloperEngagementMetric(
416 DeveloperEngagementMetric metric) const {
417 DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS);
418
419 UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric,
420 NUM_DEVELOPER_ENGAGEMENT_METRICS);
421 }
422
LogHeuristicTypePrediction(FieldTypeQualityMetric metric,ServerFieldType field_type,const std::string & experiment_id) const423 void AutofillMetrics::LogHeuristicTypePrediction(
424 FieldTypeQualityMetric metric,
425 ServerFieldType field_type,
426 const std::string& experiment_id) const {
427 LogTypeQualityMetric("Autofill.Quality.HeuristicType",
428 metric, NUM_FIELD_TYPE_QUALITY_METRICS,
429 field_type, experiment_id);
430 }
431
LogOverallTypePrediction(FieldTypeQualityMetric metric,ServerFieldType field_type,const std::string & experiment_id) const432 void AutofillMetrics::LogOverallTypePrediction(
433 FieldTypeQualityMetric metric,
434 ServerFieldType field_type,
435 const std::string& experiment_id) const {
436 LogTypeQualityMetric("Autofill.Quality.PredictedType",
437 metric, NUM_FIELD_TYPE_QUALITY_METRICS,
438 field_type, experiment_id);
439 }
440
LogServerTypePrediction(FieldTypeQualityMetric metric,ServerFieldType field_type,const std::string & experiment_id) const441 void AutofillMetrics::LogServerTypePrediction(
442 FieldTypeQualityMetric metric,
443 ServerFieldType field_type,
444 const std::string& experiment_id) const {
445 LogTypeQualityMetric("Autofill.Quality.ServerType",
446 metric, NUM_FIELD_TYPE_QUALITY_METRICS,
447 field_type, experiment_id);
448 }
449
LogQualityMetric(QualityMetric metric,const std::string & experiment_id) const450 void AutofillMetrics::LogQualityMetric(QualityMetric metric,
451 const std::string& experiment_id) const {
452 DCHECK_LT(metric, NUM_QUALITY_METRICS);
453
454 std::string histogram_name = "Autofill.Quality";
455 if (!experiment_id.empty())
456 histogram_name += "_" + experiment_id;
457
458 LogUMAHistogramEnumeration(histogram_name, metric, NUM_QUALITY_METRICS);
459 }
460
LogServerQueryMetric(ServerQueryMetric metric) const461 void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) const {
462 DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS);
463
464 UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric,
465 NUM_SERVER_QUERY_METRICS);
466 }
467
LogUserHappinessMetric(UserHappinessMetric metric) const468 void AutofillMetrics::LogUserHappinessMetric(UserHappinessMetric metric) const {
469 DCHECK_LT(metric, NUM_USER_HAPPINESS_METRICS);
470
471 UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness", metric,
472 NUM_USER_HAPPINESS_METRICS);
473 }
474
LogFormFillDurationFromLoadWithAutofill(const base::TimeDelta & duration) const475 void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill(
476 const base::TimeDelta& duration) const {
477 UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithAutofill",
478 duration,
479 base::TimeDelta::FromMilliseconds(100),
480 base::TimeDelta::FromMinutes(10),
481 50);
482 }
483
LogFormFillDurationFromLoadWithoutAutofill(const base::TimeDelta & duration) const484 void AutofillMetrics::LogFormFillDurationFromLoadWithoutAutofill(
485 const base::TimeDelta& duration) const {
486 UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithoutAutofill",
487 duration,
488 base::TimeDelta::FromMilliseconds(100),
489 base::TimeDelta::FromMinutes(10),
490 50);
491 }
492
LogFormFillDurationFromInteractionWithAutofill(const base::TimeDelta & duration) const493 void AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill(
494 const base::TimeDelta& duration) const {
495 UMA_HISTOGRAM_CUSTOM_TIMES(
496 "Autofill.FillDuration.FromInteraction.WithAutofill",
497 duration,
498 base::TimeDelta::FromMilliseconds(100),
499 base::TimeDelta::FromMinutes(10),
500 50);
501 }
502
LogFormFillDurationFromInteractionWithoutAutofill(const base::TimeDelta & duration) const503 void AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill(
504 const base::TimeDelta& duration) const {
505 UMA_HISTOGRAM_CUSTOM_TIMES(
506 "Autofill.FillDuration.FromInteraction.WithoutAutofill",
507 duration,
508 base::TimeDelta::FromMilliseconds(100),
509 base::TimeDelta::FromMinutes(10),
510 50);
511 }
512
LogIsAutofillEnabledAtStartup(bool enabled) const513 void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled) const {
514 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled);
515 }
516
LogIsAutofillEnabledAtPageLoad(bool enabled) const517 void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(bool enabled) const {
518 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.PageLoad", enabled);
519 }
520
LogStoredProfileCount(size_t num_profiles) const521 void AutofillMetrics::LogStoredProfileCount(size_t num_profiles) const {
522 UMA_HISTOGRAM_COUNTS("Autofill.StoredProfileCount", num_profiles);
523 }
524
LogAddressSuggestionsCount(size_t num_suggestions) const525 void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) const {
526 UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions);
527 }
528
LogServerExperimentIdForQuery(const std::string & experiment_id) const529 void AutofillMetrics::LogServerExperimentIdForQuery(
530 const std::string& experiment_id) const {
531 LogServerExperimentId("Autofill.ServerExperimentId.Query", experiment_id);
532 }
533
LogServerExperimentIdForUpload(const std::string & experiment_id) const534 void AutofillMetrics::LogServerExperimentIdForUpload(
535 const std::string& experiment_id) const {
536 LogServerExperimentId("Autofill.ServerExperimentId.Upload", experiment_id);
537 }
538
539 } // namespace autofill
540