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 <algorithm>
8 #include <utility>
9 #include <vector>
10 
11 #include "base/logging.h"
12 #include "base/metrics/histogram_functions.h"
13 #include "base/metrics/histogram_macros.h"
14 #include "base/metrics/user_metrics.h"
15 #include "base/strings/strcat.h"
16 #include "base/strings/string_piece.h"
17 #include "base/time/time.h"
18 #include "components/autofill/core/browser/autofill_data_util.h"
19 #include "components/autofill/core/browser/autofill_field.h"
20 #include "components/autofill/core/browser/autofill_type.h"
21 #include "components/autofill/core/browser/data_model/autofill_offer_data.h"
22 #include "components/autofill/core/browser/data_model/credit_card.h"
23 #include "components/autofill/core/browser/form_structure.h"
24 #include "components/autofill/core/browser/form_types.h"
25 #include "components/autofill/core/common/autofill_clock.h"
26 #include "components/autofill/core/common/autofill_prefs.h"
27 #include "components/autofill/core/common/autofill_tick_clock.h"
28 #include "components/autofill/core/common/form_data.h"
29 #include "components/language_usage_metrics/language_usage_metrics.h"
30 #include "services/metrics/public/cpp/metrics_utils.h"
31 #include "services/metrics/public/cpp/ukm_builders.h"
32 
33 namespace autofill {
34 
35 using mojom::SubmissionSource;
36 
37 namespace {
38 
39 // Exponential bucket spacing for UKM event data.
40 const double kAutofillEventDataBucketSpacing = 2.0;
41 
42 // Note: if adding an enum value here, update the corresponding description for
43 // AutofillTypeQualityByFieldType in histograms.xml.
44 enum FieldTypeGroupForMetrics {
45   GROUP_AMBIGUOUS = 0,
46   GROUP_NAME,
47   GROUP_COMPANY,
48   GROUP_ADDRESS_LINE_1,
49   GROUP_ADDRESS_LINE_2,
50   GROUP_ADDRESS_CITY,
51   GROUP_ADDRESS_STATE,
52   GROUP_ADDRESS_ZIP,
53   GROUP_ADDRESS_COUNTRY,
54   GROUP_ADDRESS_HOME_STREET_NAME,
55   GROUP_ADDRESS_HOME_DEPENDENT_STREET_NAME,
56   GROUP_ADDRESS_HOME_HOUSE_NUMBER,
57   GROUP_ADDRESS_HOME_PREMISE_NAME,
58   GROUP_ADDRESS_HOME_SUBPREMISE,
59   GROUP_PHONE,
60   GROUP_FAX,  // Deprecated.
61   GROUP_EMAIL,
62   GROUP_CREDIT_CARD_NAME,
63   GROUP_CREDIT_CARD_NUMBER,
64   GROUP_CREDIT_CARD_DATE,
65   GROUP_CREDIT_CARD_TYPE,
66   GROUP_PASSWORD,
67   GROUP_ADDRESS_LINE_3,
68   GROUP_USERNAME,
69   GROUP_STREET_ADDRESS,
70   GROUP_CREDIT_CARD_VERIFICATION,
71   GROUP_UNFILLABLE,
72   NUM_FIELD_TYPE_GROUPS_FOR_METRICS
73 };
74 
PreviousSaveCreditCardPromptUserDecisionToString(int previous_save_credit_card_prompt_user_decision)75 std::string PreviousSaveCreditCardPromptUserDecisionToString(
76     int previous_save_credit_card_prompt_user_decision) {
77   DCHECK_LT(previous_save_credit_card_prompt_user_decision,
78             prefs::NUM_PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISIONS);
79   std::string previous_response;
80   if (previous_save_credit_card_prompt_user_decision ==
81       prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_ACCEPTED) {
82     previous_response = ".PreviouslyAccepted";
83   } else if (previous_save_credit_card_prompt_user_decision ==
84              prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_DENIED) {
85     previous_response = ".PreviouslyDenied";
86   } else {
87     DCHECK_EQ(previous_save_credit_card_prompt_user_decision,
88               prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_NONE);
89     previous_response = ".NoPreviousDecision";
90   }
91   return previous_response;
92 }
93 
94 }  // namespace
95 
96 // First, translates |field_type| to the corresponding logical |group| from
97 // |FieldTypeGroupForMetrics|.  Then, interpolates this with the given |metric|,
98 // which should be in the range [0, |num_possible_metrics|).
99 // Returns the interpolated index.
100 //
101 // The interpolation maps the pair (|group|, |metric|) to a single index, so
102 // that all the indicies for a given group are adjacent.  In particular, with
103 // the groups {AMBIGUOUS, NAME, ...} combining with the metrics {UNKNOWN, MATCH,
104 // MISMATCH}, we create this set of mapped indices:
105 // {
106 //   AMBIGUOUS+UNKNOWN,
107 //   AMBIGUOUS+MATCH,
108 //   AMBIGUOUS+MISMATCH,
109 //   NAME+UNKNOWN,
110 //   NAME+MATCH,
111 //   NAME+MISMATCH,
112 //   ...
113 // }.
114 //
115 // Clients must ensure that |field_type| is one of the types Chrome supports
116 // natively, e.g. |field_type| must not be a billng address.
117 // NOTE: This is defined outside of the anonymous namespace so that it can be
118 // accessed from the unit test file. It is not exposed in the header file,
119 // however, because it is not intended for consumption outside of the metrics
120 // implementation.
GetFieldTypeGroupPredictionQualityMetric(ServerFieldType field_type,AutofillMetrics::FieldTypeQualityMetric metric)121 int GetFieldTypeGroupPredictionQualityMetric(
122     ServerFieldType field_type,
123     AutofillMetrics::FieldTypeQualityMetric metric) {
124   DCHECK_LT(metric, AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
125 
126   FieldTypeGroupForMetrics group = GROUP_AMBIGUOUS;
127   switch (AutofillType(field_type).group()) {
128     case NO_GROUP:
129       group = GROUP_AMBIGUOUS;
130       break;
131 
132     case NAME:
133     case NAME_BILLING:
134       group = GROUP_NAME;
135       break;
136 
137     case COMPANY:
138       group = GROUP_COMPANY;
139       break;
140 
141     case ADDRESS_HOME:
142     case ADDRESS_BILLING:
143       switch (AutofillType(field_type).GetStorableType()) {
144         case ADDRESS_HOME_LINE1:
145           group = GROUP_ADDRESS_LINE_1;
146           break;
147         case ADDRESS_HOME_LINE2:
148           group = GROUP_ADDRESS_LINE_2;
149           break;
150         case ADDRESS_HOME_LINE3:
151           group = GROUP_ADDRESS_LINE_3;
152           break;
153         case ADDRESS_HOME_STREET_ADDRESS:
154           group = GROUP_STREET_ADDRESS;
155           break;
156         case ADDRESS_HOME_CITY:
157           group = GROUP_ADDRESS_CITY;
158           break;
159         case ADDRESS_HOME_STATE:
160           group = GROUP_ADDRESS_STATE;
161           break;
162         case ADDRESS_HOME_ZIP:
163           group = GROUP_ADDRESS_ZIP;
164           break;
165         case ADDRESS_HOME_COUNTRY:
166           group = GROUP_ADDRESS_COUNTRY;
167           break;
168         case ADDRESS_HOME_STREET_NAME:
169           group = GROUP_ADDRESS_HOME_STREET_NAME;
170           break;
171         case ADDRESS_HOME_DEPENDENT_STREET_NAME:
172           group = GROUP_ADDRESS_HOME_DEPENDENT_STREET_NAME;
173           break;
174         case ADDRESS_HOME_HOUSE_NUMBER:
175           group = GROUP_ADDRESS_HOME_HOUSE_NUMBER;
176           break;
177         case ADDRESS_HOME_PREMISE_NAME:
178           group = GROUP_ADDRESS_HOME_PREMISE_NAME;
179           break;
180         case ADDRESS_HOME_SUBPREMISE:
181           group = GROUP_ADDRESS_HOME_SUBPREMISE;
182           break;
183         default:
184           NOTREACHED() << field_type << " has no group assigned (ambiguous)";
185           group = GROUP_AMBIGUOUS;
186           break;
187       }
188       break;
189 
190     case EMAIL:
191       group = GROUP_EMAIL;
192       break;
193 
194     case PHONE_HOME:
195     case PHONE_BILLING:
196       group = GROUP_PHONE;
197       break;
198 
199     case CREDIT_CARD:
200       switch (field_type) {
201         case CREDIT_CARD_NAME_FULL:
202         case CREDIT_CARD_NAME_FIRST:
203         case CREDIT_CARD_NAME_LAST:
204           group = GROUP_CREDIT_CARD_NAME;
205           break;
206         case CREDIT_CARD_NUMBER:
207           group = GROUP_CREDIT_CARD_NUMBER;
208           break;
209         case CREDIT_CARD_TYPE:
210           group = GROUP_CREDIT_CARD_TYPE;
211           break;
212         case CREDIT_CARD_EXP_MONTH:
213         case CREDIT_CARD_EXP_2_DIGIT_YEAR:
214         case CREDIT_CARD_EXP_4_DIGIT_YEAR:
215         case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR:
216         case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR:
217           group = GROUP_CREDIT_CARD_DATE;
218           break;
219         case CREDIT_CARD_VERIFICATION_CODE:
220           group = GROUP_CREDIT_CARD_VERIFICATION;
221           break;
222         default:
223           NOTREACHED() << field_type << " has no group assigned (ambiguous)";
224           group = GROUP_AMBIGUOUS;
225           break;
226       }
227       break;
228 
229     case PASSWORD_FIELD:
230       group = GROUP_PASSWORD;
231       break;
232 
233     case USERNAME_FIELD:
234       group = GROUP_USERNAME;
235       break;
236 
237     case UNFILLABLE:
238       group = GROUP_UNFILLABLE;
239       break;
240 
241     case TRANSACTION:
242       NOTREACHED();
243       break;
244   }
245 
246   // Use bits 8-15 for the group and bits 0-7 for the metric.
247   static_assert(AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS <= UINT8_MAX,
248                 "maximum field type quality metric must fit into 8 bits");
249   static_assert(NUM_FIELD_TYPE_GROUPS_FOR_METRICS <= UINT8_MAX,
250                 "number of field type groups must fit into 8 bits");
251   return (group << 8) | metric;
252 }
253 
254 // This function encodes the integer value of a |ServerFieldType| and the
255 // metric value of an |AutofilledFieldUserEdtingStatus| into a 16 bit integer.
256 // The lower four bits are used to encode the editing status and the higher
257 // 12 bits are used to encode the field type.
GetFieldTypeUserEditStatusMetric(ServerFieldType server_type,AutofillMetrics::AutofilledFieldUserEditingStatusMetric metric)258 int GetFieldTypeUserEditStatusMetric(
259     ServerFieldType server_type,
260     AutofillMetrics::AutofilledFieldUserEditingStatusMetric metric) {
261   static_assert(ServerFieldType::MAX_VALID_FIELD_TYPE <= (UINT16_MAX >> 4),
262                 "Autofill::ServerTypes value needs more than 12 bits.");
263 
264   static_assert(
265       static_cast<int>(
266           AutofillMetrics::AutofilledFieldUserEditingStatusMetric::kMaxValue) <=
267           (UINT16_MAX >> 12),
268       "AutofillMetrics::AutofilledFieldUserEditingStatusMetric value needs "
269       "more than 4 bits");
270 
271   return (server_type << 4) | static_cast<int>(metric);
272 }
273 
274 namespace {
275 
GetQualityMetricPredictionSource(AutofillMetrics::QualityMetricPredictionSource source)276 const char* GetQualityMetricPredictionSource(
277     AutofillMetrics::QualityMetricPredictionSource source) {
278   switch (source) {
279     default:
280     case AutofillMetrics::PREDICTION_SOURCE_UNKNOWN:
281       NOTREACHED();
282       return "Unknown";
283 
284     case AutofillMetrics::PREDICTION_SOURCE_HEURISTIC:
285       return "Heuristic";
286     case AutofillMetrics::PREDICTION_SOURCE_SERVER:
287       return "Server";
288     case AutofillMetrics::PREDICTION_SOURCE_OVERALL:
289       return "Overall";
290   }
291 }
292 
GetQualityMetricTypeSuffix(AutofillMetrics::QualityMetricType metric_type)293 const char* GetQualityMetricTypeSuffix(
294     AutofillMetrics::QualityMetricType metric_type) {
295   switch (metric_type) {
296     default:
297       NOTREACHED();
298       FALLTHROUGH;
299     case AutofillMetrics::TYPE_SUBMISSION:
300       return "";
301     case AutofillMetrics::TYPE_NO_SUBMISSION:
302       return ".NoSubmission";
303     case AutofillMetrics::TYPE_AUTOCOMPLETE_BASED:
304       return ".BasedOnAutocomplete";
305   }
306 }
307 
308 // Given a set of |possible_types| for a field, select the best type to use as
309 // the "actual" field type when calculating metrics. If the |predicted_type| is
310 // among the |possible_types] then use that as the best type (i.e., the
311 // prediction is deemed to have been correct).
GetActualFieldType(const ServerFieldTypeSet & possible_types,ServerFieldType predicted_type)312 ServerFieldType GetActualFieldType(const ServerFieldTypeSet& possible_types,
313                                    ServerFieldType predicted_type) {
314   DCHECK_NE(possible_types.size(), 0u);
315 
316   if (possible_types.count(EMPTY_TYPE)) {
317     DCHECK_EQ(possible_types.size(), 1u);
318     return EMPTY_TYPE;
319   }
320 
321   if (possible_types.count(UNKNOWN_TYPE)) {
322     DCHECK_EQ(possible_types.size(), 1u);
323     return UNKNOWN_TYPE;
324   }
325 
326   if (possible_types.count(predicted_type))
327     return predicted_type;
328 
329   // Collapse field types that Chrome treats as identical, e.g. home and
330   // billing address fields.
331   ServerFieldTypeSet collapsed_field_types;
332   for (const auto& type : possible_types) {
333     DCHECK_NE(type, EMPTY_TYPE);
334     DCHECK_NE(type, UNKNOWN_TYPE);
335 
336     // A phone number that's only missing its country code is (for metrics
337     // purposes) the same as the whole phone number.
338     if (type == PHONE_HOME_CITY_AND_NUMBER)
339       collapsed_field_types.insert(PHONE_HOME_WHOLE_NUMBER);
340     else
341       collapsed_field_types.insert(AutofillType(type).GetStorableType());
342   }
343 
344   // Capture the field's type, if it is unambiguous.
345   ServerFieldType actual_type = AMBIGUOUS_TYPE;
346   if (collapsed_field_types.size() == 1)
347     actual_type = *collapsed_field_types.begin();
348 
349   DVLOG(2) << "Inferred Type: " << AutofillType(actual_type).ToString();
350   return actual_type;
351 }
352 
353 // Check if the value of |field| is same as one of the previously autofilled
354 // values. This indicates a bad rationalization if |field| has
355 // only_fill_when_focued set to true.
DuplicatedFilling(const FormStructure & form,const AutofillField & field)356 bool DuplicatedFilling(const FormStructure& form, const AutofillField& field) {
357   for (const auto& form_field : form) {
358     if (field.value == form_field->value && form_field->is_autofilled)
359       return true;
360   }
361   return false;
362 }
363 
LogPredictionQualityMetricsForFieldsOnlyFilledWhenFocused(const std::string & aggregate_histogram,const std::string & type_specific_histogram,const std::string & rationalization_quality_histogram,ServerFieldType predicted_type,ServerFieldType actual_type,bool is_empty,bool is_ambiguous,bool log_rationalization_metrics,const FormStructure & form,const AutofillField & field)364 void LogPredictionQualityMetricsForFieldsOnlyFilledWhenFocused(
365     const std::string& aggregate_histogram,
366     const std::string& type_specific_histogram,
367     const std::string& rationalization_quality_histogram,
368     ServerFieldType predicted_type,
369     ServerFieldType actual_type,
370     bool is_empty,
371     bool is_ambiguous,
372     bool log_rationalization_metrics,
373     const FormStructure& form,
374     const AutofillField& field) {
375   // If it is filled with values unknown, it is a true negative.
376   if (actual_type == UNKNOWN_TYPE) {
377     // Only log aggregate true negative; do not log type specific metrics
378     // for UNKNOWN/EMPTY.
379     DVLOG(2) << "TRUE NEGATIVE";
380     base::UmaHistogramSparse(
381         aggregate_histogram,
382         (is_empty ? AutofillMetrics::TRUE_NEGATIVE_EMPTY
383                   : (is_ambiguous ? AutofillMetrics::TRUE_NEGATIVE_AMBIGUOUS
384                                   : AutofillMetrics::TRUE_NEGATIVE_UNKNOWN)));
385     if (log_rationalization_metrics) {
386       base::UmaHistogramSparse(
387           rationalization_quality_histogram,
388           (is_empty ? AutofillMetrics::RATIONALIZATION_GOOD
389                     : AutofillMetrics::RATIONALIZATION_OK));
390     }
391     return;
392   }
393 
394   // If it is filled with same type as predicted, it is a true positive. We
395   // also log an RATIONALIZATION_BAD by checking if the filled value is filled
396   // already in previous fields, this means autofill could have filled it
397   // automatically if there has been no rationalization.
398   if (predicted_type == actual_type) {
399     DVLOG(2) << "TRUE POSITIVE";
400     base::UmaHistogramSparse(aggregate_histogram,
401                              AutofillMetrics::TRUE_POSITIVE);
402     base::UmaHistogramSparse(type_specific_histogram,
403                              GetFieldTypeGroupPredictionQualityMetric(
404                                  actual_type, AutofillMetrics::TRUE_POSITIVE));
405     if (log_rationalization_metrics) {
406       bool duplicated_filling = DuplicatedFilling(form, field);
407       base::UmaHistogramSparse(
408           rationalization_quality_histogram,
409           (duplicated_filling ? AutofillMetrics::RATIONALIZATION_BAD
410                               : AutofillMetrics::RATIONALIZATION_OK));
411     }
412     return;
413   }
414 
415   DVLOG(2) << "MISMATCH";
416   // Here the prediction is wrong, but user has to provide some value still.
417   // This should be a false negative.
418   base::UmaHistogramSparse(aggregate_histogram,
419                            AutofillMetrics::FALSE_NEGATIVE_MISMATCH);
420   // Log FALSE_NEGATIVE_MISMATCH for predicted type if it did predicted
421   // something but actual type is different.
422   if (predicted_type != UNKNOWN_TYPE)
423     base::UmaHistogramSparse(
424         type_specific_histogram,
425         GetFieldTypeGroupPredictionQualityMetric(
426             predicted_type, AutofillMetrics::FALSE_NEGATIVE_MISMATCH));
427   if (log_rationalization_metrics) {
428     // Logging RATIONALIZATION_OK despite of type mismatch here because autofill
429     // would have got it wrong with or without rationalization. Rationalization
430     // here does not help, neither does it do any harm.
431     base::UmaHistogramSparse(rationalization_quality_histogram,
432                              AutofillMetrics::RATIONALIZATION_OK);
433   }
434   return;
435 }
436 
LogPredictionQualityMetricsForCommonFields(const std::string & aggregate_histogram,const std::string & type_specific_histogram,ServerFieldType predicted_type,ServerFieldType actual_type,bool is_empty,bool is_ambiguous)437 void LogPredictionQualityMetricsForCommonFields(
438     const std::string& aggregate_histogram,
439     const std::string& type_specific_histogram,
440     ServerFieldType predicted_type,
441     ServerFieldType actual_type,
442     bool is_empty,
443     bool is_ambiguous) {
444   // If the predicted and actual types match then it's either a true positive
445   // or a true negative (if they are both unknown). Do not log type specific
446   // true negatives (instead log a true positive for the "Ambiguous" type).
447   if (predicted_type == actual_type) {
448     if (actual_type == UNKNOWN_TYPE) {
449       // Only log aggregate true negative; do not log type specific metrics
450       // for UNKNOWN/EMPTY.
451       DVLOG(2) << "TRUE NEGATIVE";
452       base::UmaHistogramSparse(
453           aggregate_histogram,
454           (is_empty ? AutofillMetrics::TRUE_NEGATIVE_EMPTY
455                     : (is_ambiguous ? AutofillMetrics::TRUE_NEGATIVE_AMBIGUOUS
456                                     : AutofillMetrics::TRUE_NEGATIVE_UNKNOWN)));
457       return;
458     }
459 
460     DVLOG(2) << "TRUE POSITIVE";
461     // Log both aggregate and type specific true positive if we correctly
462     // predict that type with which the field was filled.
463     base::UmaHistogramSparse(aggregate_histogram,
464                              AutofillMetrics::TRUE_POSITIVE);
465     base::UmaHistogramSparse(type_specific_histogram,
466                              GetFieldTypeGroupPredictionQualityMetric(
467                                  actual_type, AutofillMetrics::TRUE_POSITIVE));
468     return;
469   }
470 
471   // Note: At this point predicted_type != actual type
472   // If actual type is UNKNOWN_TYPE then the prediction is a false positive.
473   // Further specialize the type of false positive by whether the field was
474   // empty or contained an unknown value.
475   if (actual_type == UNKNOWN_TYPE) {
476     DVLOG(2) << "FALSE POSITIVE";
477     auto metric =
478         (is_empty ? AutofillMetrics::FALSE_POSITIVE_EMPTY
479                   : (is_ambiguous ? AutofillMetrics::FALSE_POSITIVE_AMBIGUOUS
480                                   : AutofillMetrics::FALSE_POSITIVE_UNKNOWN));
481     base::UmaHistogramSparse(aggregate_histogram, metric);
482     base::UmaHistogramSparse(
483         type_specific_histogram,
484         GetFieldTypeGroupPredictionQualityMetric(predicted_type, metric));
485     return;
486   }
487 
488   // Note: At this point predicted_type != actual type, actual_type != UNKNOWN.
489   // If predicted type is UNKNOWN_TYPE then the prediction is a false negative
490   // unknown.
491   if (predicted_type == UNKNOWN_TYPE) {
492     DVLOG(2) << "FALSE NEGATIVE";
493     base::UmaHistogramSparse(aggregate_histogram,
494                              AutofillMetrics::FALSE_NEGATIVE_UNKNOWN);
495     base::UmaHistogramSparse(
496         type_specific_histogram,
497         GetFieldTypeGroupPredictionQualityMetric(
498             actual_type, AutofillMetrics::FALSE_NEGATIVE_UNKNOWN));
499     return;
500   }
501 
502   DVLOG(2) << "MISMATCH";
503 
504   // Note: At this point predicted_type != actual type, actual_type != UNKNOWN,
505   //       predicted_type != UNKNOWN.
506   // This is a mismatch. From the reference of the actual type, this is a false
507   // negative (it was T, but predicted U). From the reference of the prediction,
508   // this is a false positive (predicted it was T, but it was U).
509   base::UmaHistogramSparse(aggregate_histogram,
510                            AutofillMetrics::FALSE_NEGATIVE_MISMATCH);
511   base::UmaHistogramSparse(
512       type_specific_histogram,
513       GetFieldTypeGroupPredictionQualityMetric(
514           actual_type, AutofillMetrics::FALSE_NEGATIVE_MISMATCH));
515   base::UmaHistogramSparse(
516       type_specific_histogram,
517       GetFieldTypeGroupPredictionQualityMetric(
518           predicted_type, AutofillMetrics::FALSE_POSITIVE_MISMATCH));
519 }
520 
521 // Logs field type prediction quality metrics.  The primary histogram name is
522 // constructed based on |prediction_source| The field-specific histogram names
523 // also incorporates the possible and predicted types for |field|. A suffix may
524 // be appended to the metric name, depending on |metric_type|.
LogPredictionQualityMetrics(AutofillMetrics::QualityMetricPredictionSource prediction_source,ServerFieldType predicted_type,AutofillMetrics::FormInteractionsUkmLogger * form_interactions_ukm_logger,const FormStructure & form,const AutofillField & field,AutofillMetrics::QualityMetricType metric_type,bool log_rationalization_metrics)525 void LogPredictionQualityMetrics(
526     AutofillMetrics::QualityMetricPredictionSource prediction_source,
527     ServerFieldType predicted_type,
528     AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger,
529     const FormStructure& form,
530     const AutofillField& field,
531     AutofillMetrics::QualityMetricType metric_type,
532     bool log_rationalization_metrics) {
533   // Generate histogram names.
534   const char* source = GetQualityMetricPredictionSource(prediction_source);
535   const char* suffix = GetQualityMetricTypeSuffix(metric_type);
536   std::string raw_data_histogram =
537       base::JoinString({"Autofill.FieldPrediction.", source, suffix}, "");
538   std::string aggregate_histogram = base::JoinString(
539       {"Autofill.FieldPredictionQuality.Aggregate.", source, suffix}, "");
540   std::string type_specific_histogram = base::JoinString(
541       {"Autofill.FieldPredictionQuality.ByFieldType.", source, suffix}, "");
542   std::string rationalization_quality_histogram = base::JoinString(
543       {"Autofill.RationalizationQuality.PhoneNumber", suffix}, "");
544 
545   const ServerFieldTypeSet& possible_types =
546       metric_type == AutofillMetrics::TYPE_AUTOCOMPLETE_BASED
547           ? ServerFieldTypeSet{AutofillType(field.html_type(),
548                                             field.html_mode())
549                                    .GetStorableType()}
550           : field.possible_types();
551 
552   // Get the best type classification we can for the field.
553   ServerFieldType actual_type =
554       GetActualFieldType(possible_types, predicted_type);
555 
556   DVLOG(2) << "Predicted: " << AutofillType(predicted_type).ToString() << "; "
557            << "Actual: " << AutofillType(actual_type).ToString();
558 
559   DCHECK_LE(predicted_type, UINT16_MAX);
560   DCHECK_LE(actual_type, UINT16_MAX);
561   base::UmaHistogramSparse(raw_data_histogram,
562                            (predicted_type << 16) | actual_type);
563 
564   form_interactions_ukm_logger->LogFieldType(
565       form.form_parsed_timestamp(), form.form_signature(),
566       field.GetFieldSignature(), prediction_source, metric_type, predicted_type,
567       actual_type);
568 
569   // NO_SERVER_DATA is the equivalent of predicting UNKNOWN.
570   if (predicted_type == NO_SERVER_DATA)
571     predicted_type = UNKNOWN_TYPE;
572 
573   // The actual type being EMPTY_TYPE is the same as UNKNOWN_TYPE for comparison
574   // purposes, but remember whether or not it was empty for more precise logging
575   // later.
576   bool is_empty = (actual_type == EMPTY_TYPE);
577   bool is_ambiguous = (actual_type == AMBIGUOUS_TYPE);
578   if (is_empty || is_ambiguous)
579     actual_type = UNKNOWN_TYPE;
580 
581   // Log metrics for a field that is |only_fill_when_focused|==true. Basically
582   // autofill might have a field prediction but it also thinks it should not
583   // be filled automatically unless user focused on the field. This requires
584   // different metrics logging than normal fields.
585   if (field.only_fill_when_focused()) {
586     LogPredictionQualityMetricsForFieldsOnlyFilledWhenFocused(
587         aggregate_histogram, type_specific_histogram,
588         rationalization_quality_histogram, predicted_type, actual_type,
589         is_empty, is_ambiguous, log_rationalization_metrics, form, field);
590     return;
591   }
592 
593   LogPredictionQualityMetricsForCommonFields(
594       aggregate_histogram, type_specific_histogram, predicted_type, actual_type,
595       is_empty, is_ambiguous);
596 }
597 
598 }  // namespace
599 
600 const int kMaxBucketsCount = 50;
601 
602 // static
LogProfileSuggestionsMadeWithFormatter(bool made_with_formatter)603 void AutofillMetrics::LogProfileSuggestionsMadeWithFormatter(
604     bool made_with_formatter) {
605   UMA_HISTOGRAM_BOOLEAN("Autofill.ProfileSuggestionsMadeWithFormatter",
606                         made_with_formatter);
607 }
608 
609 // static
LogSubmittedCardStateMetric(SubmittedCardStateMetric metric)610 void AutofillMetrics::LogSubmittedCardStateMetric(
611     SubmittedCardStateMetric metric) {
612   DCHECK_LT(metric, NUM_SUBMITTED_CARD_STATE_METRICS);
613   UMA_HISTOGRAM_ENUMERATION("Autofill.SubmittedCardState", metric,
614                             NUM_SUBMITTED_CARD_STATE_METRICS);
615 }
616 
617 // static
LogSubmittedServerCardExpirationStatusMetric(SubmittedServerCardExpirationStatusMetric metric)618 void AutofillMetrics::LogSubmittedServerCardExpirationStatusMetric(
619     SubmittedServerCardExpirationStatusMetric metric) {
620   DCHECK_LT(metric, NUM_SUBMITTED_SERVER_CARD_EXPIRATION_STATUS_METRICS);
621   UMA_HISTOGRAM_ENUMERATION(
622       "Autofill.SubmittedServerCardExpirationStatus", metric,
623       NUM_SUBMITTED_SERVER_CARD_EXPIRATION_STATUS_METRICS);
624 }
625 
626 // static
LogCreditCardSaveNotOfferedDueToMaxStrikesMetric(SaveTypeMetric metric)627 void AutofillMetrics::LogCreditCardSaveNotOfferedDueToMaxStrikesMetric(
628     SaveTypeMetric metric) {
629   UMA_HISTOGRAM_ENUMERATION(
630       "Autofill.StrikeDatabase.CreditCardSaveNotOfferedDueToMaxStrikes",
631       metric);
632 }
633 
634 // static
LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(SaveTypeMetric metric)635 void AutofillMetrics::LogLocalCardMigrationNotOfferedDueToMaxStrikesMetric(
636     SaveTypeMetric metric) {
637   UMA_HISTOGRAM_ENUMERATION(
638       "Autofill.StrikeDatabase.LocalCardMigrationNotOfferedDueToMaxStrikes",
639       metric);
640 }
641 
642 // static
LogUploadOfferedCardOriginMetric(UploadOfferedCardOriginMetric metric)643 void AutofillMetrics::LogUploadOfferedCardOriginMetric(
644     UploadOfferedCardOriginMetric metric) {
645   DCHECK_LT(metric, NUM_UPLOAD_OFFERED_CARD_ORIGIN_METRICS);
646   UMA_HISTOGRAM_ENUMERATION("Autofill.UploadOfferedCardOrigin", metric,
647                             NUM_UPLOAD_OFFERED_CARD_ORIGIN_METRICS);
648 }
649 
650 // static
LogUploadAcceptedCardOriginMetric(UploadAcceptedCardOriginMetric metric)651 void AutofillMetrics::LogUploadAcceptedCardOriginMetric(
652     UploadAcceptedCardOriginMetric metric) {
653   DCHECK_LT(metric, NUM_UPLOAD_ACCEPTED_CARD_ORIGIN_METRICS);
654   UMA_HISTOGRAM_ENUMERATION("Autofill.UploadAcceptedCardOrigin", metric,
655                             NUM_UPLOAD_ACCEPTED_CARD_ORIGIN_METRICS);
656 }
657 
658 // static
LogSaveCardCardholderNamePrefilled(bool prefilled)659 void AutofillMetrics::LogSaveCardCardholderNamePrefilled(bool prefilled) {
660   UMA_HISTOGRAM_BOOLEAN("Autofill.SaveCardCardholderNamePrefilled", prefilled);
661 }
662 
663 // static
LogSaveCardCardholderNameWasEdited(bool edited)664 void AutofillMetrics::LogSaveCardCardholderNameWasEdited(bool edited) {
665   UMA_HISTOGRAM_BOOLEAN("Autofill.SaveCardCardholderNameWasEdited", edited);
666 }
667 
668 // static
LogCardUploadDecisionMetrics(int upload_decision_metrics)669 void AutofillMetrics::LogCardUploadDecisionMetrics(
670     int upload_decision_metrics) {
671   DCHECK(upload_decision_metrics);
672   DCHECK_LT(upload_decision_metrics, 1 << kNumCardUploadDecisionMetrics);
673 
674   for (int metric = 0; metric < kNumCardUploadDecisionMetrics; ++metric)
675     if (upload_decision_metrics & (1 << metric))
676       UMA_HISTOGRAM_ENUMERATION("Autofill.CardUploadDecisionMetric", metric,
677                                 kNumCardUploadDecisionMetrics);
678 }
679 
680 // static
LogCreditCardInfoBarMetric(InfoBarMetric metric,bool is_uploading,AutofillClient::SaveCreditCardOptions options,int previous_save_credit_card_prompt_user_decision)681 void AutofillMetrics::LogCreditCardInfoBarMetric(
682     InfoBarMetric metric,
683     bool is_uploading,
684     AutofillClient::SaveCreditCardOptions options,
685     int previous_save_credit_card_prompt_user_decision) {
686   DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
687 
688   std::string destination = is_uploading ? ".Server" : ".Local";
689   base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination,
690                                 metric, NUM_INFO_BAR_METRICS);
691   if (options.should_request_name_from_user) {
692     base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination +
693                                       ".RequestingCardholderName",
694                                   metric, NUM_INFO_BAR_METRICS);
695   }
696 
697   if (options.should_request_expiration_date_from_user) {
698     base::UmaHistogramEnumeration("Autofill.CreditCardInfoBar" + destination +
699                                       ".RequestingExpirationDate",
700                                   metric, NUM_INFO_BAR_METRICS);
701   }
702 
703   if (options.from_dynamic_change_form) {
704     base::UmaHistogramEnumeration(
705         "Autofill.CreditCardInfoBar" + destination + ".FromDynamicChangeForm",
706         metric, NUM_INFO_BAR_METRICS);
707   }
708 
709   if (options.has_non_focusable_field) {
710     base::UmaHistogramEnumeration(
711         "Autofill.CreditCardInfoBar" + destination + ".FromNonFocusableForm",
712         metric, NUM_INFO_BAR_METRICS);
713   }
714 
715   base::UmaHistogramEnumeration(
716       "Autofill.CreditCardInfoBar" + destination +
717           PreviousSaveCreditCardPromptUserDecisionToString(
718               previous_save_credit_card_prompt_user_decision),
719       metric, NUM_INFO_BAR_METRICS);
720 }
721 
722 // static
LogCreditCardFillingInfoBarMetric(InfoBarMetric metric)723 void AutofillMetrics::LogCreditCardFillingInfoBarMetric(InfoBarMetric metric) {
724   DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
725   UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardFillingInfoBar", metric,
726                             NUM_INFO_BAR_METRICS);
727 }
728 
729 // static
LogSaveCardRequestExpirationDateReasonMetric(SaveCardRequestExpirationDateReasonMetric reason)730 void AutofillMetrics::LogSaveCardRequestExpirationDateReasonMetric(
731     SaveCardRequestExpirationDateReasonMetric reason) {
732   DCHECK_LE(reason, SaveCardRequestExpirationDateReasonMetric::kMaxValue);
733   UMA_HISTOGRAM_ENUMERATION("Autofill.SaveCardRequestExpirationDateReason",
734                             reason);
735 }
736 
737 // static
LogSaveCardPromptOfferMetric(SaveCardPromptOfferMetric metric,bool is_uploading,bool is_reshow,AutofillClient::SaveCreditCardOptions options,int previous_save_credit_card_prompt_user_decision,security_state::SecurityLevel security_level,AutofillSyncSigninState sync_state)738 void AutofillMetrics::LogSaveCardPromptOfferMetric(
739     SaveCardPromptOfferMetric metric,
740     bool is_uploading,
741     bool is_reshow,
742     AutofillClient::SaveCreditCardOptions options,
743     int previous_save_credit_card_prompt_user_decision,
744     security_state::SecurityLevel security_level,
745     AutofillSyncSigninState sync_state) {
746   DCHECK_LT(metric, NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
747   std::string base_histogram_name = "Autofill.SaveCreditCardPromptOffer";
748   std::string destination = is_uploading ? ".Upload" : ".Local";
749   std::string show = is_reshow ? ".Reshows" : ".FirstShow";
750   std::string metric_with_destination_and_show =
751       base_histogram_name + destination + show;
752   base::UmaHistogramEnumeration(metric_with_destination_and_show, metric,
753                                 NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
754 
755   base::UmaHistogramEnumeration(
756       metric_with_destination_and_show + GetMetricsSyncStateSuffix(sync_state),
757       metric, NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
758 
759   if (options.should_request_name_from_user) {
760     base::UmaHistogramEnumeration(
761         metric_with_destination_and_show + ".RequestingCardholderName", metric,
762         NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
763   }
764   if (options.should_request_expiration_date_from_user) {
765     base::UmaHistogramEnumeration(
766         metric_with_destination_and_show + ".RequestingExpirationDate", metric,
767         NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
768   }
769   if (options.has_non_focusable_field) {
770     base::UmaHistogramEnumeration(
771         metric_with_destination_and_show + ".FromNonFocusableForm", metric,
772         NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
773   }
774   if (options.from_dynamic_change_form) {
775     base::UmaHistogramEnumeration(
776         metric_with_destination_and_show + ".FromDynamicChangeForm", metric,
777         NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
778   }
779 
780   base::UmaHistogramEnumeration(
781       metric_with_destination_and_show +
782           PreviousSaveCreditCardPromptUserDecisionToString(
783               previous_save_credit_card_prompt_user_decision),
784       metric, NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
785 
786   if (security_level != security_state::SecurityLevel::SECURITY_LEVEL_COUNT) {
787     base::UmaHistogramEnumeration(
788         security_state::GetSecurityLevelHistogramName(
789             base_histogram_name + destination, security_level),
790         metric, NUM_SAVE_CARD_PROMPT_OFFER_METRICS);
791   }
792 }
793 
794 // static
LogSaveCardPromptResultMetric(SaveCardPromptResultMetric metric,bool is_uploading,bool is_reshow,AutofillClient::SaveCreditCardOptions options,int previous_save_credit_card_prompt_user_decision,security_state::SecurityLevel security_level,AutofillSyncSigninState sync_state)795 void AutofillMetrics::LogSaveCardPromptResultMetric(
796     SaveCardPromptResultMetric metric,
797     bool is_uploading,
798     bool is_reshow,
799     AutofillClient::SaveCreditCardOptions options,
800     int previous_save_credit_card_prompt_user_decision,
801     security_state::SecurityLevel security_level,
802     AutofillSyncSigninState sync_state) {
803   DCHECK_LT(metric, NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
804   std::string base_histogram_name = "Autofill.SaveCreditCardPromptResult";
805   std::string destination = is_uploading ? ".Upload" : ".Local";
806   std::string show = is_reshow ? ".Reshows" : ".FirstShow";
807   std::string metric_with_destination_and_show =
808       base_histogram_name + destination + show;
809 
810   base::UmaHistogramEnumeration(metric_with_destination_and_show, metric,
811                                 NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
812 
813   base::UmaHistogramEnumeration(
814       metric_with_destination_and_show + GetMetricsSyncStateSuffix(sync_state),
815       metric, NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
816 
817   if (options.should_request_name_from_user) {
818     base::UmaHistogramEnumeration(
819         metric_with_destination_and_show + ".RequestingCardholderName", metric,
820         NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
821   }
822   if (options.should_request_expiration_date_from_user) {
823     base::UmaHistogramEnumeration(
824         metric_with_destination_and_show + ".RequestingExpirationDate", metric,
825         NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
826   }
827   if (options.has_non_focusable_field) {
828     base::UmaHistogramEnumeration(
829         metric_with_destination_and_show + ".FromNonFocusableForm", metric,
830         NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
831   }
832   if (options.from_dynamic_change_form) {
833     base::UmaHistogramEnumeration(
834         metric_with_destination_and_show + ".FromDynamicChangeForm", metric,
835         NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
836   }
837 
838   base::UmaHistogramEnumeration(
839       metric_with_destination_and_show +
840           PreviousSaveCreditCardPromptUserDecisionToString(
841               previous_save_credit_card_prompt_user_decision),
842       metric, NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
843 
844   if (security_level != security_state::SecurityLevel::SECURITY_LEVEL_COUNT) {
845     base::UmaHistogramEnumeration(
846         security_state::GetSecurityLevelHistogramName(
847             base_histogram_name + destination, security_level),
848         metric, NUM_SAVE_CARD_PROMPT_RESULT_METRICS);
849   }
850 }
851 
852 // static
LogSaveCardPromptMetric(SaveCardPromptMetric metric,bool is_uploading,bool is_reshow,AutofillClient::SaveCreditCardOptions options,int previous_save_credit_card_prompt_user_decision,security_state::SecurityLevel security_level,AutofillSyncSigninState sync_state)853 void AutofillMetrics::LogSaveCardPromptMetric(
854     SaveCardPromptMetric metric,
855     bool is_uploading,
856     bool is_reshow,
857     AutofillClient::SaveCreditCardOptions options,
858     int previous_save_credit_card_prompt_user_decision,
859     security_state::SecurityLevel security_level,
860     AutofillSyncSigninState sync_state) {
861   DCHECK_LT(metric, NUM_SAVE_CARD_PROMPT_METRICS);
862   std::string destination = is_uploading ? ".Upload" : ".Local";
863   std::string show = is_reshow ? ".Reshows" : ".FirstShow";
864   std::string metric_with_destination_and_show =
865       "Autofill.SaveCreditCardPrompt" + destination + show;
866   base::UmaHistogramEnumeration(metric_with_destination_and_show, metric,
867                                 NUM_SAVE_CARD_PROMPT_METRICS);
868   base::UmaHistogramEnumeration(
869       metric_with_destination_and_show + GetMetricsSyncStateSuffix(sync_state),
870       metric, NUM_SAVE_CARD_PROMPT_METRICS);
871   if (options.should_request_name_from_user) {
872     base::UmaHistogramEnumeration(
873         metric_with_destination_and_show + ".RequestingCardholderName", metric,
874         NUM_SAVE_CARD_PROMPT_METRICS);
875   }
876   if (options.should_request_expiration_date_from_user) {
877     base::UmaHistogramEnumeration(
878         metric_with_destination_and_show + ".RequestingExpirationDate", metric,
879         NUM_SAVE_CARD_PROMPT_METRICS);
880   }
881   if (options.has_non_focusable_field) {
882     base::UmaHistogramEnumeration(
883         metric_with_destination_and_show + ".FromNonFocusableForm", metric,
884         NUM_SAVE_CARD_PROMPT_METRICS);
885   }
886   if (options.from_dynamic_change_form) {
887     base::UmaHistogramEnumeration(
888         metric_with_destination_and_show + ".FromDynamicChangeForm", metric,
889         NUM_SAVE_CARD_PROMPT_METRICS);
890   }
891   base::UmaHistogramEnumeration(
892       metric_with_destination_and_show +
893           PreviousSaveCreditCardPromptUserDecisionToString(
894               previous_save_credit_card_prompt_user_decision),
895       metric, NUM_SAVE_CARD_PROMPT_METRICS);
896 
897   LogSaveCardPromptMetricBySecurityLevel(metric, is_uploading, security_level);
898 }
899 
900 // static
LogSaveCardPromptMetricBySecurityLevel(SaveCardPromptMetric metric,bool is_uploading,security_state::SecurityLevel security_level)901 void AutofillMetrics::LogSaveCardPromptMetricBySecurityLevel(
902     SaveCardPromptMetric metric,
903     bool is_uploading,
904     security_state::SecurityLevel security_level) {
905   // Getting a SECURITY_LEVEL_COUNT security level means that it was not
906   // possible to get the real security level. Don't log.
907   if (security_level == security_state::SecurityLevel::SECURITY_LEVEL_COUNT) {
908     return;
909   }
910 
911   std::string histogram_name = "Autofill.SaveCreditCardPrompt.";
912   if (is_uploading) {
913     histogram_name += "Upload";
914   } else {
915     histogram_name += "Local";
916   }
917 
918   base::UmaHistogramEnumeration(security_state::GetSecurityLevelHistogramName(
919                                     histogram_name, security_level),
920                                 metric, NUM_SAVE_CARD_PROMPT_METRICS);
921 }
922 
923 // static
LogCreditCardUploadLegalMessageLinkClicked()924 void AutofillMetrics::LogCreditCardUploadLegalMessageLinkClicked() {
925   base::RecordAction(base::UserMetricsAction(
926       "Autofill_CreditCardUpload_LegalMessageLinkClicked"));
927 }
928 
929 // static
LogCreditCardUploadFeedbackMetric(CreditCardUploadFeedbackMetric metric)930 void AutofillMetrics::LogCreditCardUploadFeedbackMetric(
931     CreditCardUploadFeedbackMetric metric) {
932   DCHECK_LT(metric, NUM_CREDIT_CARD_UPLOAD_FEEDBACK_METRICS);
933   UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardUploadFeedback", metric,
934                             NUM_CREDIT_CARD_UPLOAD_FEEDBACK_METRICS);
935 }
936 
937 // static
LogManageCardsPromptMetric(ManageCardsPromptMetric metric,bool is_upload_save)938 void AutofillMetrics::LogManageCardsPromptMetric(ManageCardsPromptMetric metric,
939                                                  bool is_upload_save) {
940   DCHECK_LT(metric, NUM_MANAGE_CARDS_PROMPT_METRICS);
941   std::string destination = is_upload_save ? ".Upload" : ".Local";
942   std::string metric_with_destination =
943       "Autofill.ManageCardsPrompt" + destination;
944   base::UmaHistogramEnumeration(metric_with_destination, metric,
945                                 NUM_MANAGE_CARDS_PROMPT_METRICS);
946 }
947 
948 // static
LogScanCreditCardPromptMetric(ScanCreditCardPromptMetric metric)949 void AutofillMetrics::LogScanCreditCardPromptMetric(
950     ScanCreditCardPromptMetric metric) {
951   DCHECK_LT(metric, NUM_SCAN_CREDIT_CARD_PROMPT_METRICS);
952   UMA_HISTOGRAM_ENUMERATION("Autofill.ScanCreditCardPrompt", metric,
953                             NUM_SCAN_CREDIT_CARD_PROMPT_METRICS);
954 }
955 
956 // static
LogScanCreditCardCompleted(const base::TimeDelta & duration,bool completed)957 void AutofillMetrics::LogScanCreditCardCompleted(
958     const base::TimeDelta& duration,
959     bool completed) {
960   std::string suffix = completed ? "Completed" : "Cancelled";
961   base::UmaHistogramLongTimes("Autofill.ScanCreditCard.Duration_" + suffix,
962                               duration);
963   UMA_HISTOGRAM_BOOLEAN("Autofill.ScanCreditCard.Completed", completed);
964 }
965 
966 // static
LogLocalCardMigrationDecisionMetric(LocalCardMigrationDecisionMetric metric)967 void AutofillMetrics::LogLocalCardMigrationDecisionMetric(
968     LocalCardMigrationDecisionMetric metric) {
969   UMA_HISTOGRAM_ENUMERATION("Autofill.LocalCardMigrationDecision", metric);
970 }
971 
972 // static
LogLocalCardMigrationBubbleOfferMetric(LocalCardMigrationBubbleOfferMetric metric,bool is_reshow)973 void AutofillMetrics::LogLocalCardMigrationBubbleOfferMetric(
974     LocalCardMigrationBubbleOfferMetric metric,
975     bool is_reshow) {
976   DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_BUBBLE_OFFER_METRICS);
977   std::string histogram_name = "Autofill.LocalCardMigrationBubbleOffer.";
978   histogram_name += is_reshow ? "Reshows" : "FirstShow";
979   base::UmaHistogramEnumeration(histogram_name, metric,
980                                 NUM_LOCAL_CARD_MIGRATION_BUBBLE_OFFER_METRICS);
981 }
982 
983 // static
LogLocalCardMigrationBubbleUserInteractionMetric(LocalCardMigrationBubbleUserInteractionMetric metric,bool is_reshow)984 void AutofillMetrics::LogLocalCardMigrationBubbleUserInteractionMetric(
985     LocalCardMigrationBubbleUserInteractionMetric metric,
986     bool is_reshow) {
987   DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_BUBBLE_USER_INTERACTION_METRICS);
988   std::string histogram_name =
989       "Autofill.LocalCardMigrationBubbleUserInteraction.";
990   histogram_name += is_reshow ? "Reshows" : "FirstShow";
991   base::UmaHistogramEnumeration(
992       histogram_name, metric,
993       NUM_LOCAL_CARD_MIGRATION_BUBBLE_USER_INTERACTION_METRICS);
994 }
995 
996 // static
LogLocalCardMigrationBubbleResultMetric(LocalCardMigrationBubbleResultMetric metric,bool is_reshow)997 void AutofillMetrics::LogLocalCardMigrationBubbleResultMetric(
998     LocalCardMigrationBubbleResultMetric metric,
999     bool is_reshow) {
1000   DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_BUBBLE_RESULT_METRICS);
1001   std::string suffix = is_reshow ? ".Reshows" : ".FirstShow";
1002   base::UmaHistogramEnumeration(
1003       "Autofill.LocalCardMigrationBubbleResult" + suffix, metric,
1004       NUM_LOCAL_CARD_MIGRATION_BUBBLE_RESULT_METRICS);
1005 }
1006 
1007 // static
LogLocalCardMigrationDialogOfferMetric(LocalCardMigrationDialogOfferMetric metric)1008 void AutofillMetrics::LogLocalCardMigrationDialogOfferMetric(
1009     LocalCardMigrationDialogOfferMetric metric) {
1010   DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_DIALOG_OFFER_METRICS);
1011   std::string histogram_name = "Autofill.LocalCardMigrationDialogOffer";
1012   base::UmaHistogramEnumeration(histogram_name, metric,
1013                                 NUM_LOCAL_CARD_MIGRATION_DIALOG_OFFER_METRICS);
1014 }
1015 
1016 // static
LogLocalCardMigrationDialogUserInteractionMetric(const base::TimeDelta & duration,LocalCardMigrationDialogUserInteractionMetric metric)1017 void AutofillMetrics::LogLocalCardMigrationDialogUserInteractionMetric(
1018     const base::TimeDelta& duration,
1019     LocalCardMigrationDialogUserInteractionMetric metric) {
1020   DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_DIALOG_USER_INTERACTION_METRICS);
1021   base::UmaHistogramEnumeration(
1022       "Autofill.LocalCardMigrationDialogUserInteraction", metric,
1023       NUM_LOCAL_CARD_MIGRATION_DIALOG_USER_INTERACTION_METRICS);
1024 
1025   // Do not log duration metrics for
1026   // LOCAL_CARD_MIGRATION_DIALOG_DELETE_CARD_ICON_CLICKED, as it can happen
1027   // multiple times in one dialog.
1028   std::string suffix;
1029   switch (metric) {
1030     case LOCAL_CARD_MIGRATION_DIALOG_CLOSED_SAVE_BUTTON_CLICKED:
1031       suffix = "Accepted";
1032       break;
1033     case LOCAL_CARD_MIGRATION_DIALOG_CLOSED_CANCEL_BUTTON_CLICKED:
1034       suffix = "Denied";
1035       break;
1036     case LOCAL_CARD_MIGRATION_DIALOG_CLOSED_VIEW_CARDS_BUTTON_CLICKED:
1037     case LOCAL_CARD_MIGRATION_DIALOG_CLOSED_DONE_BUTTON_CLICKED:
1038       suffix = "Closed";
1039       break;
1040     default:
1041       return;
1042   }
1043 
1044   base::UmaHistogramLongTimes(
1045       "Autofill.LocalCardMigrationDialogActiveDuration." + suffix, duration);
1046 }
1047 
1048 // static
LogLocalCardMigrationDialogUserSelectionPercentageMetric(int selected,int total)1049 void AutofillMetrics::LogLocalCardMigrationDialogUserSelectionPercentageMetric(
1050     int selected,
1051     int total) {
1052   UMA_HISTOGRAM_PERCENTAGE(
1053       "Autofill.LocalCardMigrationDialogUserSelectionPercentage",
1054       100 * selected / total);
1055 }
1056 
1057 // static
LogLocalCardMigrationPromptMetric(LocalCardMigrationOrigin local_card_migration_origin,LocalCardMigrationPromptMetric metric)1058 void AutofillMetrics::LogLocalCardMigrationPromptMetric(
1059     LocalCardMigrationOrigin local_card_migration_origin,
1060     LocalCardMigrationPromptMetric metric) {
1061   DCHECK_LT(metric, NUM_LOCAL_CARD_MIGRATION_PROMPT_METRICS);
1062   std::string histogram_name = "Autofill.LocalCardMigrationOrigin.";
1063   // Switch to different sub-histogram depending on local card migration origin.
1064   switch (local_card_migration_origin) {
1065     case LocalCardMigrationOrigin::UseOfLocalCard:
1066       histogram_name += "UseOfLocalCard";
1067       break;
1068     case LocalCardMigrationOrigin::UseOfServerCard:
1069       histogram_name += "UseOfServerCard";
1070       break;
1071     case LocalCardMigrationOrigin::SettingsPage:
1072       histogram_name += "SettingsPage";
1073       break;
1074     default:
1075       NOTREACHED();
1076       return;
1077   }
1078   base::UmaHistogramEnumeration(histogram_name, metric,
1079                                 NUM_LOCAL_CARD_MIGRATION_PROMPT_METRICS);
1080 }
1081 
1082 // static
LogSaveCardWithFirstAndLastNameOffered(bool is_local)1083 void AutofillMetrics::LogSaveCardWithFirstAndLastNameOffered(bool is_local) {
1084   std::string histogram_name = "Autofill.SaveCardWithFirstAndLastNameOffered.";
1085   histogram_name += is_local ? "Local" : "Server";
1086   base::UmaHistogramBoolean(histogram_name, true);
1087 }
1088 
1089 // static
LogSaveCardWithFirstAndLastNameComplete(bool is_local)1090 void AutofillMetrics::LogSaveCardWithFirstAndLastNameComplete(bool is_local) {
1091   std::string histogram_name = "Autofill.SaveCardWithFirstAndLastNameComplete.";
1092   histogram_name += is_local ? "Local" : "Server";
1093   base::UmaHistogramBoolean(histogram_name, true);
1094 }
1095 
1096 // static
LogCardUnmaskDurationAfterWebauthn(const base::TimeDelta & duration,AutofillClient::PaymentsRpcResult result)1097 void AutofillMetrics::LogCardUnmaskDurationAfterWebauthn(
1098     const base::TimeDelta& duration,
1099     AutofillClient::PaymentsRpcResult result) {
1100   std::string suffix;
1101   switch (result) {
1102     case AutofillClient::SUCCESS:
1103       suffix = "Success";
1104       break;
1105     case AutofillClient::TRY_AGAIN_FAILURE:
1106     case AutofillClient::PERMANENT_FAILURE:
1107       suffix = "Failure";
1108       break;
1109     case AutofillClient::NETWORK_ERROR:
1110       suffix = "NetworkError";
1111       break;
1112     case AutofillClient::NONE:
1113       NOTREACHED();
1114       return;
1115   }
1116   base::UmaHistogramLongTimes("Autofill.BetterAuth.CardUnmaskDuration.Fido",
1117                               duration);
1118   base::UmaHistogramLongTimes(
1119       "Autofill.BetterAuth.CardUnmaskDuration.Fido." + suffix, duration);
1120 }
1121 
1122 // static
LogCardUnmaskPreflightCalled()1123 void AutofillMetrics::LogCardUnmaskPreflightCalled() {
1124   UMA_HISTOGRAM_BOOLEAN("Autofill.BetterAuth.CardUnmaskPreflightCalled", true);
1125 }
1126 
1127 // static
LogCardUnmaskPreflightDuration(const base::TimeDelta & duration)1128 void AutofillMetrics::LogCardUnmaskPreflightDuration(
1129     const base::TimeDelta& duration) {
1130   base::UmaHistogramLongTimes("Autofill.BetterAuth.CardUnmaskPreflightDuration",
1131                               duration);
1132 }
1133 
1134 // static
LogWebauthnOptChangeCalled(bool request_to_opt_in,bool is_checkout_flow,WebauthnOptInParameters metric)1135 void AutofillMetrics::LogWebauthnOptChangeCalled(
1136     bool request_to_opt_in,
1137     bool is_checkout_flow,
1138     WebauthnOptInParameters metric) {
1139   if (!request_to_opt_in) {
1140     DCHECK(!is_checkout_flow);
1141     base::UmaHistogramBoolean(
1142         "Autofill.BetterAuth.OptOutCalled.FromSettingsPage", true);
1143     return;
1144   }
1145 
1146   std::string histogram_name = "Autofill.BetterAuth.OptInCalled.";
1147   histogram_name += is_checkout_flow ? "FromCheckoutFlow" : "FromSettingsPage";
1148   base::UmaHistogramEnumeration(histogram_name, metric);
1149 }
1150 
1151 // static
LogWebauthnOptInPromoShown(bool is_checkout_flow)1152 void AutofillMetrics::LogWebauthnOptInPromoShown(bool is_checkout_flow) {
1153   std::string suffix =
1154       is_checkout_flow ? "FromCheckoutFlow" : "FromSettingsPage";
1155   base::UmaHistogramBoolean("Autofill.BetterAuth.OptInPromoShown." + suffix,
1156                             true);
1157 }
1158 
1159 // static
LogWebauthnOptInPromoUserDecision(bool is_checkout_flow,WebauthnOptInPromoUserDecisionMetric metric)1160 void AutofillMetrics::LogWebauthnOptInPromoUserDecision(
1161     bool is_checkout_flow,
1162     WebauthnOptInPromoUserDecisionMetric metric) {
1163   std::string suffix =
1164       (is_checkout_flow ? "FromCheckoutFlow" : "FromSettingsPage");
1165   base::UmaHistogramEnumeration(
1166       "Autofill.BetterAuth.OptInPromoUserDecision." + suffix, metric);
1167 }
1168 
1169 // static
LogCardUnmaskTypeDecision(CardUnmaskTypeDecisionMetric metric)1170 void AutofillMetrics::LogCardUnmaskTypeDecision(
1171     CardUnmaskTypeDecisionMetric metric) {
1172   base::UmaHistogramEnumeration("Autofill.BetterAuth.CardUnmaskTypeDecision",
1173                                 metric);
1174 }
1175 
1176 // static
LogUserPerceivedLatencyOnCardSelection(PreflightCallEvent event,bool fido_auth_enabled)1177 void AutofillMetrics::LogUserPerceivedLatencyOnCardSelection(
1178     PreflightCallEvent event,
1179     bool fido_auth_enabled) {
1180   std::string histogram_name =
1181       "Autofill.BetterAuth.UserPerceivedLatencyOnCardSelection.";
1182   histogram_name += fido_auth_enabled ? "OptedIn" : "OptedOut";
1183   base::UmaHistogramEnumeration(histogram_name, event);
1184 }
1185 
1186 // static
LogUserPerceivedLatencyOnCardSelectionDuration(const base::TimeDelta duration)1187 void AutofillMetrics::LogUserPerceivedLatencyOnCardSelectionDuration(
1188     const base::TimeDelta duration) {
1189   base::UmaHistogramLongTimes(
1190       "Autofill.BetterAuth.UserPerceivedLatencyOnCardSelection.OptedIn."
1191       "Duration",
1192       duration);
1193 }
1194 
1195 // static
LogUserPerceivedLatencyOnCardSelectionTimedOut(bool did_time_out)1196 void AutofillMetrics::LogUserPerceivedLatencyOnCardSelectionTimedOut(
1197     bool did_time_out) {
1198   base::UmaHistogramBoolean(
1199       "Autofill.BetterAuth.UserPerceivedLatencyOnCardSelection.OptedIn."
1200       "TimedOutCvcFallback",
1201       did_time_out);
1202 }
1203 
LogUserVerifiabilityCheckDuration(const base::TimeDelta & duration)1204 void AutofillMetrics::LogUserVerifiabilityCheckDuration(
1205     const base::TimeDelta& duration) {
1206   base::UmaHistogramLongTimes(
1207       "Autofill.BetterAuth.UserVerifiabilityCheckDuration", duration);
1208 }
1209 
1210 // static
LogWebauthnResult(WebauthnFlowEvent event,WebauthnResultMetric metric)1211 void AutofillMetrics::LogWebauthnResult(WebauthnFlowEvent event,
1212                                         WebauthnResultMetric metric) {
1213   std::string histogram_name = "Autofill.BetterAuth.WebauthnResult.";
1214   switch (event) {
1215     case WebauthnFlowEvent::kImmediateAuthentication:
1216       histogram_name += "ImmediateAuthentication";
1217       break;
1218     case WebauthnFlowEvent::kAuthenticationAfterCvc:
1219       histogram_name += "AuthenticationAfterCVC";
1220       break;
1221     case WebauthnFlowEvent::kCheckoutOptIn:
1222       histogram_name += "CheckoutOptIn";
1223       break;
1224     case WebauthnFlowEvent::kSettingsPageOptIn:
1225       histogram_name += "SettingsPageOptIn";
1226       break;
1227   }
1228   base::UmaHistogramEnumeration(histogram_name, metric);
1229 }
1230 
1231 // static
LogUnmaskPromptEvent(UnmaskPromptEvent event,bool has_valid_nickname)1232 void AutofillMetrics::LogUnmaskPromptEvent(UnmaskPromptEvent event,
1233                                            bool has_valid_nickname) {
1234   base::UmaHistogramEnumeration("Autofill.UnmaskPrompt.Events", event,
1235                                 NUM_UNMASK_PROMPT_EVENTS);
1236   if (has_valid_nickname) {
1237     base::UmaHistogramEnumeration("Autofill.UnmaskPrompt.Events.WithNickname",
1238                                   event, NUM_UNMASK_PROMPT_EVENTS);
1239   }
1240 }
1241 
1242 // static
LogCardholderNameFixFlowPromptEvent(CardholderNameFixFlowPromptEvent event)1243 void AutofillMetrics::LogCardholderNameFixFlowPromptEvent(
1244     CardholderNameFixFlowPromptEvent event) {
1245   UMA_HISTOGRAM_ENUMERATION("Autofill.CardholderNameFixFlowPrompt.Events",
1246                             event, NUM_CARDHOLDER_NAME_FIXFLOW_PROMPT_EVENTS);
1247 }
1248 
1249 // static
LogExpirationDateFixFlowPromptEvent(ExpirationDateFixFlowPromptEvent event)1250 void AutofillMetrics::LogExpirationDateFixFlowPromptEvent(
1251     ExpirationDateFixFlowPromptEvent event) {
1252   UMA_HISTOGRAM_ENUMERATION("Autofill.ExpirationDateFixFlowPrompt.Events",
1253                             event);
1254 }
1255 
1256 // static
LogExpirationDateFixFlowPromptShown()1257 void AutofillMetrics::LogExpirationDateFixFlowPromptShown() {
1258   UMA_HISTOGRAM_BOOLEAN("Autofill.ExpirationDateFixFlowPromptShown", true);
1259 }
1260 
1261 // static
LogUnmaskPromptEventDuration(const base::TimeDelta & duration,UnmaskPromptEvent close_event,bool has_valid_nickname)1262 void AutofillMetrics::LogUnmaskPromptEventDuration(
1263     const base::TimeDelta& duration,
1264     UnmaskPromptEvent close_event,
1265     bool has_valid_nickname) {
1266   std::string suffix;
1267   switch (close_event) {
1268     case UNMASK_PROMPT_CLOSED_NO_ATTEMPTS:
1269       suffix = ".NoAttempts";
1270       break;
1271     case UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_RETRIABLE_FAILURE:
1272     case UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_NON_RETRIABLE_FAILURE:
1273       suffix = ".Failure";
1274       break;
1275     case UNMASK_PROMPT_CLOSED_ABANDON_UNMASKING:
1276       suffix = ".AbandonUnmasking";
1277       break;
1278     case UNMASK_PROMPT_UNMASKED_CARD_FIRST_ATTEMPT:
1279     case UNMASK_PROMPT_UNMASKED_CARD_AFTER_FAILED_ATTEMPTS:
1280       suffix = ".Success";
1281       break;
1282     default:
1283       NOTREACHED();
1284       return;
1285   }
1286   base::UmaHistogramLongTimes("Autofill.UnmaskPrompt.Duration", duration);
1287   base::UmaHistogramLongTimes("Autofill.UnmaskPrompt.Duration" + suffix,
1288                               duration);
1289 
1290   if (has_valid_nickname) {
1291     base::UmaHistogramLongTimes("Autofill.UnmaskPrompt.Duration.WithNickname",
1292                                 duration);
1293     base::UmaHistogramLongTimes(
1294         "Autofill.UnmaskPrompt.Duration" + suffix + ".WithNickname", duration);
1295   }
1296 }
1297 
1298 // static
LogTimeBeforeAbandonUnmasking(const base::TimeDelta & duration,bool has_valid_nickname)1299 void AutofillMetrics::LogTimeBeforeAbandonUnmasking(
1300     const base::TimeDelta& duration,
1301     bool has_valid_nickname) {
1302   base::UmaHistogramLongTimes(
1303       "Autofill.UnmaskPrompt.TimeBeforeAbandonUnmasking", duration);
1304   if (has_valid_nickname) {
1305     base::UmaHistogramLongTimes(
1306         "Autofill.UnmaskPrompt.TimeBeforeAbandonUnmasking.WithNickname",
1307         duration);
1308   }
1309 }
1310 
1311 // static
LogRealPanResult(AutofillClient::PaymentsRpcResult result)1312 void AutofillMetrics::LogRealPanResult(
1313     AutofillClient::PaymentsRpcResult result) {
1314   PaymentsRpcResult metric_result;
1315   switch (result) {
1316     case AutofillClient::SUCCESS:
1317       metric_result = PAYMENTS_RESULT_SUCCESS;
1318       break;
1319     case AutofillClient::TRY_AGAIN_FAILURE:
1320       metric_result = PAYMENTS_RESULT_TRY_AGAIN_FAILURE;
1321       break;
1322     case AutofillClient::PERMANENT_FAILURE:
1323       metric_result = PAYMENTS_RESULT_PERMANENT_FAILURE;
1324       break;
1325     case AutofillClient::NETWORK_ERROR:
1326       metric_result = PAYMENTS_RESULT_NETWORK_ERROR;
1327       break;
1328     default:
1329       NOTREACHED();
1330       return;
1331   }
1332   UMA_HISTOGRAM_ENUMERATION("Autofill.UnmaskPrompt.GetRealPanResult",
1333                             metric_result, NUM_PAYMENTS_RESULTS);
1334 }
1335 
1336 // static
LogRealPanDuration(const base::TimeDelta & duration,AutofillClient::PaymentsRpcResult result)1337 void AutofillMetrics::LogRealPanDuration(
1338     const base::TimeDelta& duration,
1339     AutofillClient::PaymentsRpcResult result) {
1340   std::string suffix;
1341   switch (result) {
1342     case AutofillClient::SUCCESS:
1343       suffix = "Success";
1344       break;
1345     case AutofillClient::TRY_AGAIN_FAILURE:
1346     case AutofillClient::PERMANENT_FAILURE:
1347       suffix = "Failure";
1348       break;
1349     case AutofillClient::NETWORK_ERROR:
1350       suffix = "NetworkError";
1351       break;
1352     default:
1353       NOTREACHED();
1354       return;
1355   }
1356   base::UmaHistogramLongTimes("Autofill.UnmaskPrompt.GetRealPanDuration",
1357                               duration);
1358   base::UmaHistogramLongTimes(
1359       "Autofill.UnmaskPrompt.GetRealPanDuration." + suffix, duration);
1360 }
1361 
1362 // static
LogUnmaskingDuration(const base::TimeDelta & duration,AutofillClient::PaymentsRpcResult result)1363 void AutofillMetrics::LogUnmaskingDuration(
1364     const base::TimeDelta& duration,
1365     AutofillClient::PaymentsRpcResult result) {
1366   std::string suffix;
1367   switch (result) {
1368     case AutofillClient::SUCCESS:
1369       suffix = "Success";
1370       break;
1371     case AutofillClient::TRY_AGAIN_FAILURE:
1372     case AutofillClient::PERMANENT_FAILURE:
1373       suffix = "Failure";
1374       break;
1375     case AutofillClient::NETWORK_ERROR:
1376       suffix = "NetworkError";
1377       break;
1378     default:
1379       NOTREACHED();
1380       return;
1381   }
1382   base::UmaHistogramLongTimes("Autofill.UnmaskPrompt.UnmaskingDuration",
1383                               duration);
1384   base::UmaHistogramLongTimes(
1385       "Autofill.UnmaskPrompt.UnmaskingDuration." + suffix, duration);
1386 }
1387 
1388 // static
LogDeveloperEngagementMetric(DeveloperEngagementMetric metric)1389 void AutofillMetrics::LogDeveloperEngagementMetric(
1390     DeveloperEngagementMetric metric) {
1391   DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS);
1392   UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric,
1393                             NUM_DEVELOPER_ENGAGEMENT_METRICS);
1394 }
1395 
LogHeuristicPredictionQualityMetrics(FormInteractionsUkmLogger * form_interactions_ukm_logger,const FormStructure & form,const AutofillField & field,QualityMetricType metric_type)1396 void AutofillMetrics::LogHeuristicPredictionQualityMetrics(
1397     FormInteractionsUkmLogger* form_interactions_ukm_logger,
1398     const FormStructure& form,
1399     const AutofillField& field,
1400     QualityMetricType metric_type) {
1401   LogPredictionQualityMetrics(
1402       PREDICTION_SOURCE_HEURISTIC,
1403       AutofillType(field.heuristic_type()).GetStorableType(),
1404       form_interactions_ukm_logger, form, field, metric_type,
1405       false /*log_rationalization_metrics*/);
1406 }
1407 
LogServerPredictionQualityMetrics(FormInteractionsUkmLogger * form_interactions_ukm_logger,const FormStructure & form,const AutofillField & field,QualityMetricType metric_type)1408 void AutofillMetrics::LogServerPredictionQualityMetrics(
1409     FormInteractionsUkmLogger* form_interactions_ukm_logger,
1410     const FormStructure& form,
1411     const AutofillField& field,
1412     QualityMetricType metric_type) {
1413   LogPredictionQualityMetrics(
1414       PREDICTION_SOURCE_SERVER,
1415       AutofillType(field.server_type()).GetStorableType(),
1416       form_interactions_ukm_logger, form, field, metric_type,
1417       false /*log_rationalization_metrics*/);
1418 }
1419 
LogOverallPredictionQualityMetrics(FormInteractionsUkmLogger * form_interactions_ukm_logger,const FormStructure & form,const AutofillField & field,QualityMetricType metric_type)1420 void AutofillMetrics::LogOverallPredictionQualityMetrics(
1421     FormInteractionsUkmLogger* form_interactions_ukm_logger,
1422     const FormStructure& form,
1423     const AutofillField& field,
1424     QualityMetricType metric_type) {
1425   LogPredictionQualityMetrics(
1426       PREDICTION_SOURCE_OVERALL, field.Type().GetStorableType(),
1427       form_interactions_ukm_logger, form, field, metric_type,
1428       true /*log_rationalization_metrics*/);
1429 }
1430 
LogEditedAutofilledFieldAtSubmission(FormInteractionsUkmLogger * form_interactions_ukm_logger,const FormStructure & form,const AutofillField & field)1431 void AutofillMetrics::LogEditedAutofilledFieldAtSubmission(
1432     FormInteractionsUkmLogger* form_interactions_ukm_logger,
1433     const FormStructure& form,
1434     const AutofillField& field) {
1435   const std::string aggregate_histogram =
1436       "Autofill.EditedAutofilledFieldAtSubmission.Aggregate";
1437   const std::string type_specific_histogram =
1438       "Autofill.EditedAutofilledFieldAtSubmission.ByFieldType";
1439 
1440   AutofilledFieldUserEditingStatusMetric editing_metric =
1441       field.previously_autofilled()
1442           ? AutofilledFieldUserEditingStatusMetric::AUTOFILLED_FIELD_WAS_EDITED
1443           : AutofilledFieldUserEditingStatusMetric::
1444                 AUTOFILLED_FIELD_WAS_NOT_EDITED;
1445 
1446   // Record the aggregated UMA statistics.
1447   base::UmaHistogramEnumeration(aggregate_histogram, editing_metric);
1448 
1449   // Record the type specific UMA statistics.
1450   base::UmaHistogramSparse(type_specific_histogram,
1451                            GetFieldTypeUserEditStatusMetric(
1452                                field.Type().GetStorableType(), editing_metric));
1453 
1454   // Record the UMA statistics spliced by the autocomplete attribute value.
1455   FormType form_type =
1456       FormTypes::FieldTypeGroupToFormType(field.Type().group());
1457   if (form_type == ADDRESS_FORM || form_type == CREDIT_CARD_FORM) {
1458     bool autocomplete_off = field.autocomplete_attribute == "off";
1459     const std::string autocomplete_histogram = base::StrCat(
1460         {"Autofill.Autocomplete.", autocomplete_off ? "Off" : "NotOff",
1461          ".EditedAutofilledFieldAtSubmission.",
1462          form_type == ADDRESS_FORM ? "Address" : "CreditCard"});
1463     base::UmaHistogramEnumeration(autocomplete_histogram, editing_metric);
1464   }
1465 
1466   // If the field was edited, record the event to UKM.
1467   if (editing_metric ==
1468       AutofilledFieldUserEditingStatusMetric::AUTOFILLED_FIELD_WAS_EDITED) {
1469     form_interactions_ukm_logger->LogEditedAutofilledFieldAtSubmission(form,
1470                                                                        field);
1471   }
1472 }
1473 
1474 // static
LogServerQueryMetric(ServerQueryMetric metric)1475 void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) {
1476   DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS);
1477   UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric,
1478                             NUM_SERVER_QUERY_METRICS);
1479 }
1480 
1481 // static
LogUserHappinessMetric(UserHappinessMetric metric,FieldTypeGroup field_type_group,security_state::SecurityLevel security_level,uint32_t profile_form_bitmask)1482 void AutofillMetrics::LogUserHappinessMetric(
1483     UserHappinessMetric metric,
1484     FieldTypeGroup field_type_group,
1485     security_state::SecurityLevel security_level,
1486     uint32_t profile_form_bitmask) {
1487   LogUserHappinessMetric(
1488       metric, {FormTypes::FieldTypeGroupToFormType(field_type_group)},
1489       security_level, profile_form_bitmask);
1490 }
1491 
1492 // static
LogUserHappinessMetric(UserHappinessMetric metric,const std::set<FormType> & form_types,security_state::SecurityLevel security_level,uint32_t profile_form_bitmask)1493 void AutofillMetrics::LogUserHappinessMetric(
1494     UserHappinessMetric metric,
1495     const std::set<FormType>& form_types,
1496     security_state::SecurityLevel security_level,
1497     uint32_t profile_form_bitmask) {
1498   DCHECK_LT(metric, NUM_USER_HAPPINESS_METRICS);
1499   UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness", metric,
1500                             NUM_USER_HAPPINESS_METRICS);
1501   if (base::Contains(form_types, CREDIT_CARD_FORM)) {
1502     UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness.CreditCard", metric,
1503                               NUM_USER_HAPPINESS_METRICS);
1504     LogUserHappinessBySecurityLevel(metric, CREDIT_CARD_FORM, security_level);
1505   }
1506   if (base::Contains(form_types, ADDRESS_FORM)) {
1507     UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness.Address", metric,
1508                               NUM_USER_HAPPINESS_METRICS);
1509     if (metric != AutofillMetrics::FORMS_LOADED) {
1510       LogUserHappinessByProfileFormType(metric, profile_form_bitmask);
1511     }
1512     LogUserHappinessBySecurityLevel(metric, ADDRESS_FORM, security_level);
1513   }
1514   if (base::Contains(form_types, PASSWORD_FORM)) {
1515     UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness.Password", metric,
1516                               NUM_USER_HAPPINESS_METRICS);
1517     LogUserHappinessBySecurityLevel(metric, PASSWORD_FORM, security_level);
1518   }
1519   if (base::Contains(form_types, UNKNOWN_FORM_TYPE)) {
1520     UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness.Unknown", metric,
1521                               NUM_USER_HAPPINESS_METRICS);
1522     LogUserHappinessBySecurityLevel(metric, UNKNOWN_FORM_TYPE, security_level);
1523   }
1524 }
1525 
1526 // static
LogUserHappinessBySecurityLevel(UserHappinessMetric metric,FormType form_type,security_state::SecurityLevel security_level)1527 void AutofillMetrics::LogUserHappinessBySecurityLevel(
1528     UserHappinessMetric metric,
1529     FormType form_type,
1530     security_state::SecurityLevel security_level) {
1531   if (security_level == security_state::SecurityLevel::SECURITY_LEVEL_COUNT) {
1532     return;
1533   }
1534 
1535   std::string histogram_name = "Autofill.UserHappiness.";
1536   switch (form_type) {
1537     case CREDIT_CARD_FORM:
1538       histogram_name += "CreditCard";
1539       break;
1540 
1541     case ADDRESS_FORM:
1542       histogram_name += "Address";
1543       break;
1544 
1545     case PASSWORD_FORM:
1546       histogram_name += "Password";
1547       break;
1548 
1549     case UNKNOWN_FORM_TYPE:
1550       histogram_name += "Unknown";
1551       break;
1552 
1553     default:
1554       NOTREACHED();
1555       return;
1556   }
1557 
1558   base::UmaHistogramEnumeration(security_state::GetSecurityLevelHistogramName(
1559                                     histogram_name, security_level),
1560                                 metric, NUM_USER_HAPPINESS_METRICS);
1561 }
1562 
1563 // static
LogUserHappinessByProfileFormType(UserHappinessMetric metric,uint32_t profile_form_bitmask)1564 void AutofillMetrics::LogUserHappinessByProfileFormType(
1565     UserHappinessMetric metric,
1566     uint32_t profile_form_bitmask) {
1567   base::UmaHistogramEnumeration(
1568       "Autofill.UserHappiness.Address" +
1569           data_util::GetSuffixForProfileFormType(profile_form_bitmask),
1570       metric, NUM_USER_HAPPINESS_METRICS);
1571 
1572   if (data_util::ContainsAddress(profile_form_bitmask) &&
1573       (data_util::ContainsPhone(profile_form_bitmask) ||
1574        data_util::ContainsEmail(profile_form_bitmask)))
1575     base::UmaHistogramEnumeration(
1576         "Autofill.UserHappiness.Address.AddressPlusContact", metric,
1577         NUM_USER_HAPPINESS_METRICS);
1578 }
1579 
1580 // static
LogFormFillDurationFromLoadWithAutofill(const base::TimeDelta & duration)1581 void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill(
1582     const base::TimeDelta& duration) {
1583   LogFormFillDuration("Autofill.FillDuration.FromLoad.WithAutofill", duration);
1584 }
1585 
1586 // static
LogFormFillDurationFromLoadWithoutAutofill(const base::TimeDelta & duration)1587 void AutofillMetrics::LogFormFillDurationFromLoadWithoutAutofill(
1588     const base::TimeDelta& duration) {
1589   LogFormFillDuration("Autofill.FillDuration.FromLoad.WithoutAutofill",
1590                       duration);
1591 }
1592 
1593 // static
LogFormFillDurationFromInteraction(const std::set<FormType> & form_types,bool used_autofill,const base::TimeDelta & duration)1594 void AutofillMetrics::LogFormFillDurationFromInteraction(
1595     const std::set<FormType>& form_types,
1596     bool used_autofill,
1597     const base::TimeDelta& duration) {
1598   std::string parent_metric;
1599   if (used_autofill) {
1600     parent_metric = "Autofill.FillDuration.FromInteraction.WithAutofill";
1601   } else {
1602     parent_metric = "Autofill.FillDuration.FromInteraction.WithoutAutofill";
1603   }
1604   LogFormFillDuration(parent_metric, duration);
1605   if (base::Contains(form_types, CREDIT_CARD_FORM)) {
1606     LogFormFillDuration(parent_metric + ".CreditCard", duration);
1607   }
1608   if (base::Contains(form_types, ADDRESS_FORM)) {
1609     LogFormFillDuration(parent_metric + ".Address", duration);
1610   }
1611   if (base::Contains(form_types, PASSWORD_FORM)) {
1612     LogFormFillDuration(parent_metric + ".Password", duration);
1613   }
1614   if (base::Contains(form_types, UNKNOWN_FORM_TYPE)) {
1615     LogFormFillDuration(parent_metric + ".Unknown", duration);
1616   }
1617 }
1618 
1619 // static
LogFormFillDuration(const std::string & metric,const base::TimeDelta & duration)1620 void AutofillMetrics::LogFormFillDuration(const std::string& metric,
1621                                           const base::TimeDelta& duration) {
1622   base::UmaHistogramCustomTimes(metric, duration,
1623                                 base::TimeDelta::FromMilliseconds(100),
1624                                 base::TimeDelta::FromMinutes(10), 50);
1625 }
1626 
1627 // static
LogIsAutofillEnabledAtStartup(bool enabled)1628 void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled) {
1629   UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled);
1630 }
1631 
1632 // static
LogIsAutofillProfileEnabledAtStartup(bool enabled)1633 void AutofillMetrics::LogIsAutofillProfileEnabledAtStartup(bool enabled) {
1634   UMA_HISTOGRAM_BOOLEAN("Autofill.Address.IsEnabled.Startup", enabled);
1635 }
1636 
1637 // static
LogIsAutofillCreditCardEnabledAtStartup(bool enabled)1638 void AutofillMetrics::LogIsAutofillCreditCardEnabledAtStartup(bool enabled) {
1639   UMA_HISTOGRAM_BOOLEAN("Autofill.CreditCard.IsEnabled.Startup", enabled);
1640 }
1641 
1642 // static
LogIsAutofillEnabledAtPageLoad(bool enabled,AutofillSyncSigninState sync_state)1643 void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(
1644     bool enabled,
1645     AutofillSyncSigninState sync_state) {
1646   std::string name("Autofill.IsEnabled.PageLoad");
1647   UMA_HISTOGRAM_BOOLEAN(name, enabled);
1648   base::UmaHistogramBoolean(name + GetMetricsSyncStateSuffix(sync_state),
1649                             enabled);
1650 }
1651 
1652 // static
LogIsAutofillProfileEnabledAtPageLoad(bool enabled,AutofillSyncSigninState sync_state)1653 void AutofillMetrics::LogIsAutofillProfileEnabledAtPageLoad(
1654     bool enabled,
1655     AutofillSyncSigninState sync_state) {
1656   std::string name("Autofill.Address.IsEnabled.PageLoad");
1657   UMA_HISTOGRAM_BOOLEAN(name, enabled);
1658   base::UmaHistogramBoolean(name + GetMetricsSyncStateSuffix(sync_state),
1659                             enabled);
1660 }
1661 
1662 // static
LogIsAutofillCreditCardEnabledAtPageLoad(bool enabled,AutofillSyncSigninState sync_state)1663 void AutofillMetrics::LogIsAutofillCreditCardEnabledAtPageLoad(
1664     bool enabled,
1665     AutofillSyncSigninState sync_state) {
1666   std::string name("Autofill.CreditCard.IsEnabled.PageLoad");
1667   UMA_HISTOGRAM_BOOLEAN(name, enabled);
1668   base::UmaHistogramBoolean(name + GetMetricsSyncStateSuffix(sync_state),
1669                             enabled);
1670 }
1671 
1672 // static
LogStoredProfileCount(size_t num_profiles)1673 void AutofillMetrics::LogStoredProfileCount(size_t num_profiles) {
1674   UMA_HISTOGRAM_COUNTS_1M("Autofill.StoredProfileCount", num_profiles);
1675 }
1676 
1677 // static
LogStoredProfileDisusedCount(size_t num_profiles)1678 void AutofillMetrics::LogStoredProfileDisusedCount(size_t num_profiles) {
1679   UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredProfileDisusedCount", num_profiles);
1680 }
1681 
1682 // static
LogStoredProfileDaysSinceLastUse(size_t days)1683 void AutofillMetrics::LogStoredProfileDaysSinceLastUse(size_t days) {
1684   UMA_HISTOGRAM_COUNTS_1000("Autofill.DaysSinceLastUse.StoredProfile", days);
1685 }
1686 
1687 // static
LogStoredCreditCardMetrics(const std::vector<std::unique_ptr<CreditCard>> & local_cards,const std::vector<std::unique_ptr<CreditCard>> & server_cards,base::TimeDelta disused_data_threshold)1688 void AutofillMetrics::LogStoredCreditCardMetrics(
1689     const std::vector<std::unique_ptr<CreditCard>>& local_cards,
1690     const std::vector<std::unique_ptr<CreditCard>>& server_cards,
1691     base::TimeDelta disused_data_threshold) {
1692   size_t num_local_cards = 0;
1693   size_t num_local_cards_with_nickname = 0;
1694   size_t num_masked_cards = 0;
1695   size_t num_masked_cards_with_nickname = 0;
1696   size_t num_unmasked_cards = 0;
1697   size_t num_disused_local_cards = 0;
1698   size_t num_disused_masked_cards = 0;
1699   size_t num_disused_unmasked_cards = 0;
1700 
1701   // Concatenate the local and server cards into one big collection of raw
1702   // CreditCard pointers.
1703   std::vector<const CreditCard*> credit_cards;
1704   credit_cards.reserve(local_cards.size() + server_cards.size());
1705   for (const auto* collection : {&local_cards, &server_cards}) {
1706     for (const auto& card : *collection) {
1707       credit_cards.push_back(card.get());
1708     }
1709   }
1710 
1711   // Iterate over all of the cards and gather metrics.
1712   const base::Time now = AutofillClock::Now();
1713   for (const CreditCard* card : credit_cards) {
1714     const base::TimeDelta time_since_last_use = now - card->use_date();
1715     const int days_since_last_use = time_since_last_use.InDays();
1716     const int disused_delta =
1717         (time_since_last_use > disused_data_threshold) ? 1 : 0;
1718     UMA_HISTOGRAM_COUNTS_1000("Autofill.DaysSinceLastUse.StoredCreditCard",
1719                               days_since_last_use);
1720     switch (card->record_type()) {
1721       case CreditCard::LOCAL_CARD:
1722         UMA_HISTOGRAM_COUNTS_1000(
1723             "Autofill.DaysSinceLastUse.StoredCreditCard.Local",
1724             days_since_last_use);
1725         num_local_cards += 1;
1726         num_disused_local_cards += disused_delta;
1727         if (card->HasNonEmptyValidNickname())
1728           num_local_cards_with_nickname += 1;
1729         break;
1730       case CreditCard::MASKED_SERVER_CARD:
1731         UMA_HISTOGRAM_COUNTS_1000(
1732             "Autofill.DaysSinceLastUse.StoredCreditCard.Server",
1733             days_since_last_use);
1734         UMA_HISTOGRAM_COUNTS_1000(
1735             "Autofill.DaysSinceLastUse.StoredCreditCard.Server.Masked",
1736             days_since_last_use);
1737         num_masked_cards += 1;
1738         num_disused_masked_cards += disused_delta;
1739         if (card->HasNonEmptyValidNickname())
1740           num_masked_cards_with_nickname += 1;
1741         break;
1742       case CreditCard::FULL_SERVER_CARD:
1743         UMA_HISTOGRAM_COUNTS_1000(
1744             "Autofill.DaysSinceLastUse.StoredCreditCard.Server",
1745             days_since_last_use);
1746         UMA_HISTOGRAM_COUNTS_1000(
1747             "Autofill.DaysSinceLastUse.StoredCreditCard.Server.Unmasked",
1748             days_since_last_use);
1749         num_unmasked_cards += 1;
1750         num_disused_unmasked_cards += disused_delta;
1751         break;
1752     }
1753   }
1754 
1755   // Calculate some summary info.
1756   const size_t num_server_cards = num_masked_cards + num_unmasked_cards;
1757   const size_t num_cards = num_local_cards + num_server_cards;
1758   const size_t num_disused_server_cards =
1759       num_disused_masked_cards + num_disused_unmasked_cards;
1760   const size_t num_disused_cards =
1761       num_disused_local_cards + num_disused_server_cards;
1762 
1763   // Log the overall counts.
1764   UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardCount", num_cards);
1765   UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardCount.Local",
1766                             num_local_cards);
1767   UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardCount.Local.WithNickname",
1768                             num_local_cards_with_nickname);
1769   UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardCount.Server",
1770                             num_server_cards);
1771   UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardCount.Server.Masked",
1772                             num_masked_cards);
1773   UMA_HISTOGRAM_COUNTS_1000(
1774       "Autofill.StoredCreditCardCount.Server.Masked.WithNickname",
1775       num_masked_cards_with_nickname);
1776   UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardCount.Server.Unmasked",
1777                             num_unmasked_cards);
1778 
1779   // For card types held by the user, log how many are disused.
1780   if (num_cards) {
1781     UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardDisusedCount",
1782                               num_disused_cards);
1783   }
1784   if (num_local_cards) {
1785     UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardDisusedCount.Local",
1786                               num_disused_local_cards);
1787   }
1788   if (num_server_cards) {
1789     UMA_HISTOGRAM_COUNTS_1000("Autofill.StoredCreditCardDisusedCount.Server",
1790                               num_disused_server_cards);
1791   }
1792   if (num_masked_cards) {
1793     UMA_HISTOGRAM_COUNTS_1000(
1794         "Autofill.StoredCreditCardDisusedCount.Server.Masked",
1795         num_disused_masked_cards);
1796   }
1797   if (num_unmasked_cards) {
1798     UMA_HISTOGRAM_COUNTS_1000(
1799         "Autofill.StoredCreditCardDisusedCount.Server.Unmasked",
1800         num_disused_unmasked_cards);
1801   }
1802 }
1803 
1804 // static
LogStoredOfferMetrics(const std::vector<std::unique_ptr<AutofillOfferData>> & offers)1805 void AutofillMetrics::LogStoredOfferMetrics(
1806     const std::vector<std::unique_ptr<AutofillOfferData>>& offers) {
1807   base::UmaHistogramCounts1000("Autofill.Offer.StoredOfferCount",
1808                                offers.size());
1809 
1810   for (const std::unique_ptr<AutofillOfferData>& offer : offers) {
1811     base::UmaHistogramCounts1000(
1812         "Autofill.Offer.StoredOfferRelatedMerchantCount",
1813         offer->merchant_domain.size());
1814     base::UmaHistogramCounts1000("Autofill.Offer.StoredOfferRelatedCardCount",
1815                                  offer->eligible_instrument_id.size());
1816   }
1817 }
1818 
1819 // static
LogSyncedOfferDataBeingValid(bool valid)1820 void AutofillMetrics::LogSyncedOfferDataBeingValid(bool valid) {
1821   base::UmaHistogramBoolean("Autofill.Offer.SyncedOfferDataBeingValid", valid);
1822 }
1823 
1824 // static
LogNumberOfCreditCardsSuppressedForDisuse(size_t num_cards)1825 void AutofillMetrics::LogNumberOfCreditCardsSuppressedForDisuse(
1826     size_t num_cards) {
1827   UMA_HISTOGRAM_COUNTS_1000("Autofill.CreditCardsSuppressedForDisuse",
1828                             num_cards);
1829 }
1830 
1831 // static
LogNumberOfCreditCardsDeletedForDisuse(size_t num_cards)1832 void AutofillMetrics::LogNumberOfCreditCardsDeletedForDisuse(size_t num_cards) {
1833   UMA_HISTOGRAM_COUNTS_1000("Autofill.CreditCardsDeletedForDisuse", num_cards);
1834 }
1835 
1836 // static
LogHiddenOrPresentationalSelectFieldsFilled()1837 void AutofillMetrics::LogHiddenOrPresentationalSelectFieldsFilled() {
1838   UMA_HISTOGRAM_BOOLEAN("Autofill.HiddenOrPresentationalSelectFieldsFilled",
1839                         true);
1840 }
1841 
1842 // static
LogNumberOfProfilesAtAutofillableFormSubmission(size_t num_profiles)1843 void AutofillMetrics::LogNumberOfProfilesAtAutofillableFormSubmission(
1844     size_t num_profiles) {
1845   UMA_HISTOGRAM_COUNTS_1M(
1846       "Autofill.StoredProfileCountAtAutofillableFormSubmission", num_profiles);
1847 }
1848 
1849 // static
LogNumberOfAddressesSuppressedForDisuse(size_t num_profiles)1850 void AutofillMetrics::LogNumberOfAddressesSuppressedForDisuse(
1851     size_t num_profiles) {
1852   UMA_HISTOGRAM_COUNTS_1000("Autofill.AddressesSuppressedForDisuse",
1853                             num_profiles);
1854 }
1855 
1856 // static
LogNumberOfAddressesDeletedForDisuse(size_t num_profiles)1857 void AutofillMetrics::LogNumberOfAddressesDeletedForDisuse(
1858     size_t num_profiles) {
1859   UMA_HISTOGRAM_COUNTS_1000("Autofill.AddressesDeletedForDisuse", num_profiles);
1860 }
1861 
1862 // static
LogAddressSuggestionsCount(size_t num_suggestions)1863 void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) {
1864   UMA_HISTOGRAM_COUNTS_1M("Autofill.AddressSuggestionsCount", num_suggestions);
1865 }
1866 
1867 // static
LogAutofillSuggestionAcceptedIndex(int index,PopupType popup_type,bool off_the_record)1868 void AutofillMetrics::LogAutofillSuggestionAcceptedIndex(int index,
1869                                                          PopupType popup_type,
1870                                                          bool off_the_record) {
1871   base::UmaHistogramSparse("Autofill.SuggestionAcceptedIndex",
1872                            std::min(index, kMaxBucketsCount));
1873 
1874   if (popup_type == PopupType::kCreditCards) {
1875     base::UmaHistogramSparse("Autofill.SuggestionAcceptedIndex.CreditCard",
1876                              std::min(index, kMaxBucketsCount));
1877   } else if (popup_type == PopupType::kAddresses ||
1878              popup_type == PopupType::kPersonalInformation) {
1879     base::UmaHistogramSparse("Autofill.SuggestionAcceptedIndex.Profile",
1880                              std::min(index, kMaxBucketsCount));
1881   } else {
1882     base::UmaHistogramSparse("Autofill.SuggestionAcceptedIndex.Other",
1883                              std::min(index, kMaxBucketsCount));
1884   }
1885 
1886   base::RecordAction(base::UserMetricsAction("Autofill_SelectedSuggestion"));
1887 
1888   base::UmaHistogramBoolean("Autofill.SuggestionAccepted.OffTheRecord",
1889                             off_the_record);
1890 }
1891 
1892 // static
LogAutofillFormCleared()1893 void AutofillMetrics::LogAutofillFormCleared() {
1894   base::RecordAction(base::UserMetricsAction("Autofill_ClearedForm"));
1895 }
1896 
1897 // static
LogNumberOfEditedAutofilledFields(size_t num_edited_autofilled_fields,bool observed_submission)1898 void AutofillMetrics::LogNumberOfEditedAutofilledFields(
1899     size_t num_edited_autofilled_fields,
1900     bool observed_submission) {
1901   if (observed_submission) {
1902     UMA_HISTOGRAM_COUNTS_1000(
1903         "Autofill.NumberOfEditedAutofilledFieldsAtSubmission",
1904         num_edited_autofilled_fields);
1905   } else {
1906     UMA_HISTOGRAM_COUNTS_1000(
1907         "Autofill.NumberOfEditedAutofilledFieldsAtSubmission.NoSubmission",
1908         num_edited_autofilled_fields);
1909   }
1910 }
1911 
1912 // static
LogServerResponseHasDataForForm(bool has_data)1913 void AutofillMetrics::LogServerResponseHasDataForForm(bool has_data) {
1914   UMA_HISTOGRAM_BOOLEAN("Autofill.ServerResponseHasDataForForm", has_data);
1915 }
1916 
1917 // static
LogProfileActionOnFormSubmitted(AutofillProfileAction action)1918 void AutofillMetrics::LogProfileActionOnFormSubmitted(
1919     AutofillProfileAction action) {
1920   UMA_HISTOGRAM_ENUMERATION("Autofill.ProfileActionOnFormSubmitted", action,
1921                             AUTOFILL_PROFILE_ACTION_ENUM_SIZE);
1922 }
1923 
1924 // static
LogAutofillFormSubmittedState(AutofillFormSubmittedState state,bool is_for_credit_card,bool has_upi_vpa_field,const std::set<FormType> & form_types,const base::TimeTicks & form_parsed_timestamp,FormSignature form_signature,AutofillMetrics::FormInteractionsUkmLogger * form_interactions_ukm_logger)1925 void AutofillMetrics::LogAutofillFormSubmittedState(
1926     AutofillFormSubmittedState state,
1927     bool is_for_credit_card,
1928     bool has_upi_vpa_field,
1929     const std::set<FormType>& form_types,
1930     const base::TimeTicks& form_parsed_timestamp,
1931     FormSignature form_signature,
1932     AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger) {
1933   UMA_HISTOGRAM_ENUMERATION("Autofill.FormSubmittedState", state,
1934                             AUTOFILL_FORM_SUBMITTED_STATE_ENUM_SIZE);
1935 
1936   switch (state) {
1937     case NON_FILLABLE_FORM_OR_NEW_DATA:
1938       base::RecordAction(
1939           base::UserMetricsAction("Autofill_FormSubmitted_NonFillable"));
1940       break;
1941 
1942     case FILLABLE_FORM_AUTOFILLED_ALL:
1943       base::RecordAction(
1944           base::UserMetricsAction("Autofill_FormSubmitted_FilledAll"));
1945       break;
1946 
1947     case FILLABLE_FORM_AUTOFILLED_SOME:
1948       base::RecordAction(
1949           base::UserMetricsAction("Autofill_FormSubmitted_FilledSome"));
1950       break;
1951 
1952     case FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS:
1953       base::RecordAction(base::UserMetricsAction(
1954           "Autofill_FormSubmitted_FilledNone_SuggestionsShown"));
1955       break;
1956 
1957     case FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS:
1958       base::RecordAction(base::UserMetricsAction(
1959           "Autofill_FormSubmitted_FilledNone_SuggestionsNotShown"));
1960       break;
1961 
1962     default:
1963       NOTREACHED();
1964       break;
1965   }
1966   form_interactions_ukm_logger->LogFormSubmitted(
1967       is_for_credit_card, has_upi_vpa_field, form_types, state,
1968       form_parsed_timestamp, form_signature);
1969 }
1970 
1971 // static
LogDetermineHeuristicTypesTiming(const base::TimeDelta & duration)1972 void AutofillMetrics::LogDetermineHeuristicTypesTiming(
1973     const base::TimeDelta& duration) {
1974   UMA_HISTOGRAM_TIMES("Autofill.Timing.DetermineHeuristicTypes", duration);
1975 }
1976 
1977 // static
LogParseFormTiming(const base::TimeDelta & duration)1978 void AutofillMetrics::LogParseFormTiming(const base::TimeDelta& duration) {
1979   UMA_HISTOGRAM_TIMES("Autofill.Timing.ParseForm", duration);
1980 }
1981 
1982 // static
LogNumberOfProfilesConsideredForDedupe(size_t num_considered)1983 void AutofillMetrics::LogNumberOfProfilesConsideredForDedupe(
1984     size_t num_considered) {
1985   // A maximum of 50 is enforced to reduce the number of generated buckets.
1986   UMA_HISTOGRAM_COUNTS_1000(
1987       "Autofill.NumberOfProfilesConsideredForDedupe",
1988       std::min(static_cast<int>(num_considered), kMaxBucketsCount));
1989 }
1990 
1991 // static
LogNumberOfProfilesRemovedDuringDedupe(size_t num_removed)1992 void AutofillMetrics::LogNumberOfProfilesRemovedDuringDedupe(
1993     size_t num_removed) {
1994   // A maximum of 50 is enforced to reduce the number of generated buckets.
1995   UMA_HISTOGRAM_COUNTS_1000(
1996       "Autofill.NumberOfProfilesRemovedDuringDedupe",
1997       std::min(static_cast<int>(num_removed), kMaxBucketsCount));
1998 }
1999 
2000 // static
LogIsQueriedCreditCardFormSecure(bool is_secure)2001 void AutofillMetrics::LogIsQueriedCreditCardFormSecure(bool is_secure) {
2002   UMA_HISTOGRAM_BOOLEAN("Autofill.QueriedCreditCardFormIsSecure", is_secure);
2003 }
2004 
2005 // static
LogWalletAddressConversionType(WalletAddressConversionType type)2006 void AutofillMetrics::LogWalletAddressConversionType(
2007     WalletAddressConversionType type) {
2008   DCHECK_LT(type, NUM_CONVERTED_ADDRESS_CONVERSION_TYPES);
2009   UMA_HISTOGRAM_ENUMERATION("Autofill.WalletAddressConversionType", type,
2010                             NUM_CONVERTED_ADDRESS_CONVERSION_TYPES);
2011 }
2012 
2013 // static
LogShowedHttpNotSecureExplanation()2014 void AutofillMetrics::LogShowedHttpNotSecureExplanation() {
2015   base::RecordAction(
2016       base::UserMetricsAction("Autofill_ShowedHttpNotSecureExplanation"));
2017 }
2018 
2019 // static
LogAutocompleteDaysSinceLastUse(size_t days)2020 void AutofillMetrics::LogAutocompleteDaysSinceLastUse(size_t days) {
2021   UMA_HISTOGRAM_COUNTS_1000("Autocomplete.DaysSinceLastUse", days);
2022 }
2023 
2024 // static
LogAutocompleteSuggestionAcceptedIndex(int index)2025 void AutofillMetrics::LogAutocompleteSuggestionAcceptedIndex(int index) {
2026   base::UmaHistogramSparse("Autofill.SuggestionAcceptedIndex.Autocomplete",
2027                            std::min(index, kMaxBucketsCount));
2028   AutofillMetrics::Log(AutocompleteEvent::AUTOCOMPLETE_SUGGESTION_SELECTED);
2029 }
2030 
2031 // static
LogAutocompleteQuery(bool created)2032 void AutofillMetrics::LogAutocompleteQuery(bool created) {
2033   UMA_HISTOGRAM_BOOLEAN("Autofill.AutocompleteQuery", created);
2034 }
2035 
2036 // static
LogAutocompleteSuggestions(bool has_suggestions)2037 void AutofillMetrics::LogAutocompleteSuggestions(bool has_suggestions) {
2038   UMA_HISTOGRAM_BOOLEAN("Autofill.AutocompleteSuggestions", has_suggestions);
2039 }
2040 
2041 // static
OnAutocompleteSuggestionsShown()2042 void AutofillMetrics::OnAutocompleteSuggestionsShown() {
2043   AutofillMetrics::Log(AutocompleteEvent::AUTOCOMPLETE_SUGGESTIONS_SHOWN);
2044 }
2045 
LogNumberOfAutocompleteEntriesCleanedUp(int nb_entries)2046 void AutofillMetrics::LogNumberOfAutocompleteEntriesCleanedUp(int nb_entries) {
2047   UMA_HISTOGRAM_COUNTS_1000("Autocomplete.Cleanup", nb_entries);
2048 }
2049 
2050 // static
Log(AutocompleteEvent event)2051 void AutofillMetrics::Log(AutocompleteEvent event) {
2052   DCHECK_LT(event, AutocompleteEvent::NUM_AUTOCOMPLETE_EVENTS);
2053   std::string name("Autocomplete.Events");
2054 
2055   base::UmaHistogramEnumeration(name, event, NUM_AUTOCOMPLETE_EVENTS);
2056 }
2057 
2058 // static
SubmissionSourceToUploadEventMetric(SubmissionSource source)2059 const char* AutofillMetrics::SubmissionSourceToUploadEventMetric(
2060     SubmissionSource source) {
2061   switch (source) {
2062     case SubmissionSource::NONE:
2063       return "Autofill.UploadEvent.None";
2064     case SubmissionSource::SAME_DOCUMENT_NAVIGATION:
2065       return "Autofill.UploadEvent.SameDocumentNavigation";
2066     case SubmissionSource::XHR_SUCCEEDED:
2067       return "Autofill.UploadEvent.XhrSucceeded";
2068     case SubmissionSource::FRAME_DETACHED:
2069       return "Autofill.UploadEvent.FrameDetached";
2070     case SubmissionSource::DOM_MUTATION_AFTER_XHR:
2071       return "Autofill.UploadEvent.DomMutationAfterXhr";
2072     case SubmissionSource::PROBABLY_FORM_SUBMITTED:
2073       return "Autofill.UploadEvent.ProbablyFormSubmitted";
2074     case SubmissionSource::FORM_SUBMISSION:
2075       return "Autofill.UploadEvent.FormSubmission";
2076   }
2077   // Unittests exercise this path, so do not put NOTREACHED() here.
2078   return "Autofill.UploadEvent.Unknown";
2079 }
2080 
2081 // static
LogUploadEvent(SubmissionSource submission_source,bool was_sent)2082 void AutofillMetrics::LogUploadEvent(SubmissionSource submission_source,
2083                                      bool was_sent) {
2084   UMA_HISTOGRAM_BOOLEAN("Autofill.UploadEvent", was_sent);
2085   base::UmaHistogramEnumeration(
2086       SubmissionSourceToUploadEventMetric(submission_source),
2087       was_sent ? UploadEventStatus::kSent : UploadEventStatus::kNotSent);
2088 }
2089 
2090 // static
LogCardUploadDecisionsUkm(ukm::UkmRecorder * ukm_recorder,ukm::SourceId source_id,const GURL & url,int upload_decision_metrics)2091 void AutofillMetrics::LogCardUploadDecisionsUkm(ukm::UkmRecorder* ukm_recorder,
2092                                                 ukm::SourceId source_id,
2093                                                 const GURL& url,
2094                                                 int upload_decision_metrics) {
2095   DCHECK(upload_decision_metrics);
2096   DCHECK_LT(upload_decision_metrics, 1 << kNumCardUploadDecisionMetrics);
2097   if (!url.is_valid())
2098     return;
2099   ukm::builders::Autofill_CardUploadDecision(source_id)
2100       .SetUploadDecision(upload_decision_metrics)
2101       .Record(ukm_recorder);
2102 }
2103 
2104 // static
LogDeveloperEngagementUkm(ukm::UkmRecorder * ukm_recorder,ukm::SourceId source_id,const GURL & url,bool is_for_credit_card,std::set<FormType> form_types,int developer_engagement_metrics,FormSignature form_signature)2105 void AutofillMetrics::LogDeveloperEngagementUkm(
2106     ukm::UkmRecorder* ukm_recorder,
2107     ukm::SourceId source_id,
2108     const GURL& url,
2109     bool is_for_credit_card,
2110     std::set<FormType> form_types,
2111     int developer_engagement_metrics,
2112     FormSignature form_signature) {
2113   DCHECK(developer_engagement_metrics);
2114   DCHECK_LT(developer_engagement_metrics,
2115             1 << NUM_DEVELOPER_ENGAGEMENT_METRICS);
2116   if (!url.is_valid())
2117     return;
2118 
2119   ukm::builders::Autofill_DeveloperEngagement(source_id)
2120       .SetDeveloperEngagement(developer_engagement_metrics)
2121       .SetIsForCreditCard(is_for_credit_card)
2122       .SetFormTypes(FormTypesToBitVector(form_types))
2123       .SetFormSignature(HashFormSignature(form_signature))
2124       .Record(ukm_recorder);
2125 }
2126 
FormInteractionsUkmLogger(ukm::UkmRecorder * ukm_recorder,const ukm::SourceId source_id)2127 AutofillMetrics::FormInteractionsUkmLogger::FormInteractionsUkmLogger(
2128     ukm::UkmRecorder* ukm_recorder,
2129     const ukm::SourceId source_id)
2130     : ukm_recorder_(ukm_recorder), source_id_(source_id) {}
2131 
OnFormsParsed(const ukm::SourceId source_id)2132 void AutofillMetrics::FormInteractionsUkmLogger::OnFormsParsed(
2133     const ukm::SourceId source_id) {
2134   if (!CanLog())
2135     return;
2136 
2137   source_id_ = source_id;
2138 }
2139 
LogInteractedWithForm(bool is_for_credit_card,size_t local_record_type_count,size_t server_record_type_count,FormSignature form_signature)2140 void AutofillMetrics::FormInteractionsUkmLogger::LogInteractedWithForm(
2141     bool is_for_credit_card,
2142     size_t local_record_type_count,
2143     size_t server_record_type_count,
2144     FormSignature form_signature) {
2145   if (!CanLog())
2146     return;
2147 
2148   ukm::builders::Autofill_InteractedWithForm(source_id_)
2149       .SetIsForCreditCard(is_for_credit_card)
2150       .SetLocalRecordTypeCount(local_record_type_count)
2151       .SetServerRecordTypeCount(server_record_type_count)
2152       .SetFormSignature(HashFormSignature(form_signature))
2153       .Record(ukm_recorder_);
2154 }
2155 
LogSuggestionsShown(const FormStructure & form,const AutofillField & field,const base::TimeTicks & form_parsed_timestamp,bool off_the_record)2156 void AutofillMetrics::FormInteractionsUkmLogger::LogSuggestionsShown(
2157     const FormStructure& form,
2158     const AutofillField& field,
2159     const base::TimeTicks& form_parsed_timestamp,
2160     bool off_the_record) {
2161   if (!CanLog())
2162     return;
2163 
2164   ukm::builders::Autofill_SuggestionsShown(source_id_)
2165       .SetHeuristicType(static_cast<int>(field.heuristic_type()))
2166       .SetHtmlFieldType(static_cast<int>(field.html_type()))
2167       .SetServerType(static_cast<int>(field.server_type()))
2168       .SetFormSignature(HashFormSignature(form.form_signature()))
2169       .SetFieldSignature(HashFieldSignature(field.GetFieldSignature()))
2170       .SetMillisecondsSinceFormParsed(
2171           MillisecondsSinceFormParsed(form_parsed_timestamp))
2172       .Record(ukm_recorder_);
2173 
2174   base::UmaHistogramBoolean("Autofill.SuggestionShown.OffTheRecord",
2175                             off_the_record);
2176 }
2177 
LogDidFillSuggestion(int record_type,bool is_for_credit_card,const FormStructure & form,const AutofillField & field)2178 void AutofillMetrics::FormInteractionsUkmLogger::LogDidFillSuggestion(
2179     int record_type,
2180     bool is_for_credit_card,
2181     const FormStructure& form,
2182     const AutofillField& field) {
2183   if (!CanLog())
2184     return;
2185 
2186   ukm::builders::Autofill_SuggestionFilled(source_id_)
2187       .SetRecordType(record_type)
2188       .SetIsForCreditCard(is_for_credit_card)
2189       .SetMillisecondsSinceFormParsed(
2190           MillisecondsSinceFormParsed(form.form_parsed_timestamp()))
2191       .SetFormSignature(HashFormSignature(form.form_signature()))
2192       .SetFieldSignature(HashFieldSignature(field.GetFieldSignature()))
2193       .Record(ukm_recorder_);
2194 }
2195 
2196 void AutofillMetrics::FormInteractionsUkmLogger::
LogEditedAutofilledFieldAtSubmission(const FormStructure & form,const AutofillField & field)2197     LogEditedAutofilledFieldAtSubmission(const FormStructure& form,
2198                                          const AutofillField& field) {
2199   if (!CanLog())
2200     return;
2201 
2202   ukm::builders::Autofill_EditedAutofilledFieldAtSubmission(source_id_)
2203       .SetFieldSignature(HashFieldSignature(field.GetFieldSignature()))
2204       .SetFormSignature(HashFormSignature(form.form_signature()))
2205       .SetOverallType(static_cast<int64_t>(field.Type().GetStorableType()))
2206       .Record(ukm_recorder_);
2207 }
2208 
LogTextFieldDidChange(const FormStructure & form,const AutofillField & field)2209 void AutofillMetrics::FormInteractionsUkmLogger::LogTextFieldDidChange(
2210     const FormStructure& form,
2211     const AutofillField& field) {
2212   if (!CanLog())
2213     return;
2214 
2215   ukm::builders::Autofill_TextFieldDidChange(source_id_)
2216       .SetFormSignature(HashFormSignature(form.form_signature()))
2217       .SetFieldSignature(HashFieldSignature(field.GetFieldSignature()))
2218       .SetFieldTypeGroup(static_cast<int>(field.Type().group()))
2219       .SetHeuristicType(static_cast<int>(field.heuristic_type()))
2220       .SetServerType(static_cast<int>(field.server_type()))
2221       .SetHtmlFieldType(static_cast<int>(field.html_type()))
2222       .SetHtmlFieldMode(static_cast<int>(field.html_mode()))
2223       .SetIsAutofilled(field.is_autofilled)
2224       .SetIsEmpty(field.IsEmpty())
2225       .SetMillisecondsSinceFormParsed(
2226           MillisecondsSinceFormParsed(form.form_parsed_timestamp()))
2227       .Record(ukm_recorder_);
2228 }
2229 
LogFieldFillStatus(const FormStructure & form,const AutofillField & field,QualityMetricType metric_type)2230 void AutofillMetrics::FormInteractionsUkmLogger::LogFieldFillStatus(
2231     const FormStructure& form,
2232     const AutofillField& field,
2233     QualityMetricType metric_type) {
2234   if (!CanLog())
2235     return;
2236 
2237   ukm::builders::Autofill_FieldFillStatus(source_id_)
2238       .SetMillisecondsSinceFormParsed(
2239           MillisecondsSinceFormParsed(form.form_parsed_timestamp()))
2240       .SetFormSignature(HashFormSignature(form.form_signature()))
2241       .SetFieldSignature(HashFieldSignature(field.GetFieldSignature()))
2242       .SetValidationEvent(static_cast<int64_t>(metric_type))
2243       .SetIsAutofilled(static_cast<int64_t>(field.is_autofilled))
2244       .SetWasPreviouslyAutofilled(
2245           static_cast<int64_t>(field.previously_autofilled()))
2246       .Record(ukm_recorder_);
2247 }
2248 
2249 // TODO(szhangcs): Take FormStructure and AutofillField and extract
2250 // FormSignature and TimeTicks inside the function.
LogFieldType(const base::TimeTicks & form_parsed_timestamp,FormSignature form_signature,FieldSignature field_signature,QualityMetricPredictionSource prediction_source,QualityMetricType metric_type,ServerFieldType predicted_type,ServerFieldType actual_type)2251 void AutofillMetrics::FormInteractionsUkmLogger::LogFieldType(
2252     const base::TimeTicks& form_parsed_timestamp,
2253     FormSignature form_signature,
2254     FieldSignature field_signature,
2255     QualityMetricPredictionSource prediction_source,
2256     QualityMetricType metric_type,
2257     ServerFieldType predicted_type,
2258     ServerFieldType actual_type) {
2259   if (!CanLog())
2260     return;
2261 
2262   ukm::builders::Autofill_FieldTypeValidation(source_id_)
2263       .SetMillisecondsSinceFormParsed(
2264           MillisecondsSinceFormParsed(form_parsed_timestamp))
2265       .SetFormSignature(HashFormSignature(form_signature))
2266       .SetFieldSignature(HashFieldSignature(field_signature))
2267       .SetValidationEvent(static_cast<int64_t>(metric_type))
2268       .SetPredictionSource(static_cast<int64_t>(prediction_source))
2269       .SetPredictedType(static_cast<int64_t>(predicted_type))
2270       .SetActualType(static_cast<int64_t>(actual_type))
2271       .Record(ukm_recorder_);
2272 }
2273 
2274 void AutofillMetrics::FormInteractionsUkmLogger::
LogHiddenRepresentationalFieldSkipDecision(const FormStructure & form,const AutofillField & field,bool is_skipped)2275     LogHiddenRepresentationalFieldSkipDecision(const FormStructure& form,
2276                                                const AutofillField& field,
2277                                                bool is_skipped) {
2278   if (!CanLog())
2279     return;
2280 
2281   ukm::builders::Autofill_HiddenRepresentationalFieldSkipDecision(source_id_)
2282       .SetFormSignature(HashFormSignature(form.form_signature()))
2283       .SetFieldSignature(HashFieldSignature(field.GetFieldSignature()))
2284       .SetFieldTypeGroup(static_cast<int>(field.Type().group()))
2285       .SetFieldOverallType(static_cast<int>(field.Type().GetStorableType()))
2286       .SetHeuristicType(static_cast<int>(field.heuristic_type()))
2287       .SetServerType(static_cast<int>(field.server_type()))
2288       .SetHtmlFieldType(static_cast<int>(field.html_type()))
2289       .SetHtmlFieldMode(static_cast<int>(field.html_mode()))
2290       .SetIsSkipped(is_skipped)
2291       .Record(ukm_recorder_);
2292 }
2293 
2294 void AutofillMetrics::FormInteractionsUkmLogger::
LogRepeatedServerTypePredictionRationalized(const FormSignature form_signature,const AutofillField & field,ServerFieldType old_type)2295     LogRepeatedServerTypePredictionRationalized(
2296         const FormSignature form_signature,
2297         const AutofillField& field,
2298         ServerFieldType old_type) {
2299   if (!CanLog())
2300     return;
2301 
2302   ukm::builders::Autofill_RepeatedServerTypePredictionRationalized(source_id_)
2303       .SetFormSignature(HashFormSignature(form_signature))
2304       .SetFieldSignature(HashFieldSignature(field.GetFieldSignature()))
2305       .SetFieldTypeGroup(static_cast<int>(field.Type().group()))
2306       .SetFieldNewOverallType(static_cast<int>(field.Type().GetStorableType()))
2307       .SetHeuristicType(static_cast<int>(field.heuristic_type()))
2308       .SetHtmlFieldType(static_cast<int>(field.html_type()))
2309       .SetHtmlFieldMode(static_cast<int>(field.html_mode()))
2310       .SetServerType(static_cast<int>(field.server_type()))
2311       .SetFieldOldOverallType(static_cast<int>(old_type))
2312       .Record(ukm_recorder_);
2313 }
2314 
FormTypesToBitVector(const std::set<FormType> & form_types)2315 int64_t AutofillMetrics::FormTypesToBitVector(
2316     const std::set<FormType>& form_types) {
2317   int64_t form_type_bv = 0;
2318   for (const FormType& form_type : form_types) {
2319     DCHECK_LT(static_cast<int64_t>(form_type), 63);
2320     form_type_bv |= 1LL << static_cast<int64_t>(form_type);
2321   }
2322   return form_type_bv;
2323 }
2324 
LogServerCardLinkClicked(AutofillSyncSigninState sync_state)2325 void AutofillMetrics::LogServerCardLinkClicked(
2326     AutofillSyncSigninState sync_state) {
2327   UMA_HISTOGRAM_ENUMERATION("Autofill.ServerCardLinkClicked", sync_state,
2328                             AutofillSyncSigninState::kNumSyncStates);
2329 }
2330 
LogWalletSyncTransportCardsOptIn(bool is_opted_in)2331 void AutofillMetrics::LogWalletSyncTransportCardsOptIn(bool is_opted_in) {
2332   UMA_HISTOGRAM_BOOLEAN(
2333       "Autofill.HadUserOptedIn_To_WalletSyncTransportServerCards", is_opted_in);
2334 }
2335 
LogCardUploadEnabledMetric(CardUploadEnabledMetric metric_value,AutofillSyncSigninState sync_state)2336 void AutofillMetrics::LogCardUploadEnabledMetric(
2337     CardUploadEnabledMetric metric_value,
2338     AutofillSyncSigninState sync_state) {
2339   const std::string parent_metric = std::string("Autofill.CardUploadEnabled");
2340   base::UmaHistogramEnumeration(parent_metric, metric_value);
2341 
2342   const std::string child_metric =
2343       parent_metric + GetMetricsSyncStateSuffix(sync_state);
2344   base::UmaHistogramEnumeration(child_metric, metric_value);
2345 }
2346 
2347 // static
GetMetricsSyncStateSuffix(AutofillSyncSigninState sync_state)2348 const char* AutofillMetrics::GetMetricsSyncStateSuffix(
2349     AutofillSyncSigninState sync_state) {
2350   switch (sync_state) {
2351     case AutofillSyncSigninState::kSignedOut:
2352       return ".SignedOut";
2353     case AutofillSyncSigninState::kSignedIn:
2354       return ".SignedIn";
2355     case AutofillSyncSigninState::kSignedInAndWalletSyncTransportEnabled:
2356       return ".SignedInAndWalletSyncTransportEnabled";
2357     case AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled:
2358       return ".SignedInAndSyncFeatureEnabled";
2359     case AutofillSyncSigninState::kSyncPaused:
2360       return ".SyncPaused";
2361     case AutofillSyncSigninState::kNumSyncStates:
2362       return ".Unknown";
2363   }
2364 }
2365 
LogFormSubmitted(bool is_for_credit_card,bool has_upi_vpa_field,const std::set<FormType> & form_types,AutofillFormSubmittedState state,const base::TimeTicks & form_parsed_timestamp,FormSignature form_signature)2366 void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
2367     bool is_for_credit_card,
2368     bool has_upi_vpa_field,
2369     const std::set<FormType>& form_types,
2370     AutofillFormSubmittedState state,
2371     const base::TimeTicks& form_parsed_timestamp,
2372     FormSignature form_signature) {
2373   if (!CanLog())
2374     return;
2375 
2376   ukm::builders::Autofill_FormSubmitted builder(source_id_);
2377   builder.SetAutofillFormSubmittedState(static_cast<int>(state))
2378       .SetIsForCreditCard(is_for_credit_card)
2379       .SetHasUpiVpaField(has_upi_vpa_field)
2380       .SetFormTypes(FormTypesToBitVector(form_types))
2381       .SetFormSignature(HashFormSignature(form_signature));
2382   if (form_parsed_timestamp.is_null())
2383     DCHECK(state == NON_FILLABLE_FORM_OR_NEW_DATA ||
2384            state == FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS)
2385         << state;
2386   else
2387     builder.SetMillisecondsSinceFormParsed(
2388         MillisecondsSinceFormParsed(form_parsed_timestamp));
2389 
2390   builder.Record(ukm_recorder_);
2391 }
2392 
LogFormEvent(FormEvent form_event,const std::set<FormType> & form_types,const base::TimeTicks & form_parsed_timestamp)2393 void AutofillMetrics::FormInteractionsUkmLogger::LogFormEvent(
2394     FormEvent form_event,
2395     const std::set<FormType>& form_types,
2396     const base::TimeTicks& form_parsed_timestamp) {
2397   if (!CanLog())
2398     return;
2399 
2400   if (form_parsed_timestamp.is_null())
2401     return;
2402 
2403   ukm::builders::Autofill_FormEvent builder(source_id_);
2404   builder.SetAutofillFormEvent(static_cast<int>(form_event))
2405       .SetFormTypes(FormTypesToBitVector(form_types))
2406       .SetMillisecondsSinceFormParsed(
2407           MillisecondsSinceFormParsed(form_parsed_timestamp))
2408       .Record(ukm_recorder_);
2409 }
2410 
CanLog() const2411 bool AutofillMetrics::FormInteractionsUkmLogger::CanLog() const {
2412   return ukm_recorder_ != nullptr;
2413 }
2414 
MillisecondsSinceFormParsed(const base::TimeTicks & form_parsed_timestamp) const2415 int64_t AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormParsed(
2416     const base::TimeTicks& form_parsed_timestamp) const {
2417   DCHECK(!form_parsed_timestamp.is_null());
2418   // Use the pinned timestamp as the current time if it's set.
2419   base::TimeTicks now = pinned_timestamp_.is_null()
2420                             ? AutofillTickClock::NowTicks()
2421                             : pinned_timestamp_;
2422 
2423   return ukm::GetExponentialBucketMin(
2424       (now - form_parsed_timestamp).InMilliseconds(),
2425       kAutofillEventDataBucketSpacing);
2426 }
2427 
UkmTimestampPin(FormInteractionsUkmLogger * logger)2428 AutofillMetrics::UkmTimestampPin::UkmTimestampPin(
2429     FormInteractionsUkmLogger* logger)
2430     : logger_(logger) {
2431   DCHECK(logger_);
2432   DCHECK(!logger_->has_pinned_timestamp());
2433   logger_->set_pinned_timestamp(AutofillTickClock::NowTicks());
2434 }
2435 
~UkmTimestampPin()2436 AutofillMetrics::UkmTimestampPin::~UkmTimestampPin() {
2437   DCHECK(logger_->has_pinned_timestamp());
2438   logger_->set_pinned_timestamp(base::TimeTicks());
2439 }
2440 
2441 // static
LogAddressFormImportRequirementMetric(AutofillMetrics::AddressProfileImportRequirementMetric metric)2442 void AutofillMetrics::LogAddressFormImportRequirementMetric(
2443     AutofillMetrics::AddressProfileImportRequirementMetric metric) {
2444   // Shift the requirement type index by one bit to the right.
2445   // The freed least significant bit is used to indicate the fulfillment status
2446   // of the specific requirement.
2447   base::UmaHistogramEnumeration("Autofill.AddressProfileImportRequirements",
2448                                 metric);
2449 }
2450 
2451 // static
2452 void AutofillMetrics::
LogAddressFormImportCountrySpecificFieldRequirementsMetric(bool is_zip_missing,bool is_state_missing,bool is_city_missing,bool is_line1_missing)2453     LogAddressFormImportCountrySpecificFieldRequirementsMetric(
2454         bool is_zip_missing,
2455         bool is_state_missing,
2456         bool is_city_missing,
2457         bool is_line1_missing) {
2458   const auto metric = static_cast<
2459       AutofillMetrics::
2460           AddressProfileImportCountrySpecificFieldRequirementsMetric>(
2461       (is_zip_missing ? 0b1 : 0) | (is_state_missing ? 0b10 : 0) |
2462       (is_city_missing ? 0b100 : 0) | (is_line1_missing ? 0b1000 : 0));
2463   base::UmaHistogramEnumeration(
2464       "Autofill.AddressProfileImportCountrySpecificFieldRequirements", metric);
2465 }
2466 
2467 // static
LogAddressFormImportStatustMetric(AutofillMetrics::AddressProfileImportStatusMetric metric)2468 void AutofillMetrics::LogAddressFormImportStatustMetric(
2469     AutofillMetrics::AddressProfileImportStatusMetric metric) {
2470   base::UmaHistogramEnumeration("Autofill.AddressProfileImportStatus", metric);
2471 }
2472 
2473 // static
LogFieldParsingPageTranslationStatusMetric(bool metric)2474 void AutofillMetrics::LogFieldParsingPageTranslationStatusMetric(bool metric) {
2475   base::UmaHistogramBoolean("Autofill.ParsedFieldTypesWasPageTranslated",
2476                             metric);
2477 }
2478 
2479 // static
LogFieldParsingTranslatedFormLanguageMetric(base::StringPiece locale)2480 void AutofillMetrics::LogFieldParsingTranslatedFormLanguageMetric(
2481     base::StringPiece locale) {
2482   base::UmaHistogramSparse(
2483       "Autofill.ParsedFieldTypesUsingTranslatedPageLanguage",
2484       language_usage_metrics::LanguageUsageMetrics::ToLanguageCode(locale));
2485 }
2486 
2487 // static
LogWebOTPPhoneCollectionMetricStateUkm(ukm::UkmRecorder * recorder,ukm::SourceId source_id,uint32_t phone_collection_metric_state)2488 void AutofillMetrics::LogWebOTPPhoneCollectionMetricStateUkm(
2489     ukm::UkmRecorder* recorder,
2490     ukm::SourceId source_id,
2491     uint32_t phone_collection_metric_state) {
2492   // UKM recording is not supported for WebViews.
2493   if (!recorder || source_id == ukm::kInvalidSourceId)
2494     return;
2495 
2496   ukm::builders::WebOTPImpact builder(source_id);
2497   builder.SetPhoneCollection(phone_collection_metric_state);
2498   builder.Record(recorder);
2499 }
2500 
2501 }  // namespace autofill
2502