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