Include all dupe types (event when value is zero) in scan stats.
[chromium-blink-merge.git] / components / autofill / core / browser / autofill_metrics.cc
blobebf5a6dec83cc36d9327d7f58283db26d829ccc5
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.
5 #include "components/autofill/core/browser/autofill_metrics.h"
7 #include "base/logging.h"
8 #include "base/metrics/histogram.h"
9 #include "base/metrics/sparse_histogram.h"
10 #include "base/time/time.h"
11 #include "components/autofill/core/browser/autofill_type.h"
12 #include "components/autofill/core/browser/form_structure.h"
13 #include "components/autofill/core/common/form_data.h"
15 namespace autofill {
17 namespace {
19 enum FieldTypeGroupForMetrics {
20 GROUP_AMBIGUOUS = 0,
21 GROUP_NAME,
22 GROUP_COMPANY,
23 GROUP_ADDRESS_LINE_1,
24 GROUP_ADDRESS_LINE_2,
25 GROUP_ADDRESS_CITY,
26 GROUP_ADDRESS_STATE,
27 GROUP_ADDRESS_ZIP,
28 GROUP_ADDRESS_COUNTRY,
29 GROUP_PHONE,
30 GROUP_FAX, // Deprecated.
31 GROUP_EMAIL,
32 GROUP_CREDIT_CARD_NAME,
33 GROUP_CREDIT_CARD_NUMBER,
34 GROUP_CREDIT_CARD_DATE,
35 GROUP_CREDIT_CARD_TYPE,
36 GROUP_PASSWORD,
37 GROUP_ADDRESS_LINE_3,
38 GROUP_USERNAME,
39 NUM_FIELD_TYPE_GROUPS_FOR_METRICS
42 } // namespace
44 // First, translates |field_type| to the corresponding logical |group| from
45 // |FieldTypeGroupForMetrics|. Then, interpolates this with the given |metric|,
46 // which should be in the range [0, |num_possible_metrics|).
47 // Returns the interpolated index.
49 // The interpolation maps the pair (|group|, |metric|) to a single index, so
50 // that all the indicies for a given group are adjacent. In particular, with
51 // the groups {AMBIGUOUS, NAME, ...} combining with the metrics {UNKNOWN, MATCH,
52 // MISMATCH}, we create this set of mapped indices:
53 // {
54 // AMBIGUOUS+UNKNOWN,
55 // AMBIGUOUS+MATCH,
56 // AMBIGUOUS+MISMATCH,
57 // NAME+UNKNOWN,
58 // NAME+MATCH,
59 // NAME+MISMATCH,
60 // ...
61 // }.
63 // Clients must ensure that |field_type| is one of the types Chrome supports
64 // natively, e.g. |field_type| must not be a billng address.
65 // NOTE: This is defined outside of the anonymous namespace so that it can be
66 // accessed from the unit test file. It is not exposed in the header file,
67 // however, because it is not intended for consumption outside of the metrics
68 // implementation.
69 int GetFieldTypeGroupMetric(ServerFieldType field_type,
70 AutofillMetrics::FieldTypeQualityMetric metric) {
71 DCHECK_LT(metric, AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
73 FieldTypeGroupForMetrics group = GROUP_AMBIGUOUS;
74 switch (AutofillType(field_type).group()) {
75 case NO_GROUP:
76 group = GROUP_AMBIGUOUS;
77 break;
79 case NAME:
80 case NAME_BILLING:
81 group = GROUP_NAME;
82 break;
84 case COMPANY:
85 group = GROUP_COMPANY;
86 break;
88 case ADDRESS_HOME:
89 case ADDRESS_BILLING:
90 switch (AutofillType(field_type).GetStorableType()) {
91 case ADDRESS_HOME_LINE1:
92 group = GROUP_ADDRESS_LINE_1;
93 break;
94 case ADDRESS_HOME_LINE2:
95 group = GROUP_ADDRESS_LINE_2;
96 break;
97 case ADDRESS_HOME_LINE3:
98 group = GROUP_ADDRESS_LINE_3;
99 break;
100 case ADDRESS_HOME_CITY:
101 group = GROUP_ADDRESS_CITY;
102 break;
103 case ADDRESS_HOME_STATE:
104 group = GROUP_ADDRESS_STATE;
105 break;
106 case ADDRESS_HOME_ZIP:
107 group = GROUP_ADDRESS_ZIP;
108 break;
109 case ADDRESS_HOME_COUNTRY:
110 group = GROUP_ADDRESS_COUNTRY;
111 break;
112 default:
113 NOTREACHED();
114 group = GROUP_AMBIGUOUS;
115 break;
117 break;
119 case EMAIL:
120 group = GROUP_EMAIL;
121 break;
123 case PHONE_HOME:
124 case PHONE_BILLING:
125 group = GROUP_PHONE;
126 break;
128 case CREDIT_CARD:
129 switch (field_type) {
130 case CREDIT_CARD_NAME:
131 group = GROUP_CREDIT_CARD_NAME;
132 break;
133 case CREDIT_CARD_NUMBER:
134 group = GROUP_CREDIT_CARD_NUMBER;
135 break;
136 case CREDIT_CARD_TYPE:
137 group = GROUP_CREDIT_CARD_TYPE;
138 break;
139 case CREDIT_CARD_EXP_MONTH:
140 case CREDIT_CARD_EXP_2_DIGIT_YEAR:
141 case CREDIT_CARD_EXP_4_DIGIT_YEAR:
142 case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR:
143 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR:
144 group = GROUP_CREDIT_CARD_DATE;
145 break;
146 default:
147 NOTREACHED();
148 group = GROUP_AMBIGUOUS;
149 break;
151 break;
153 case PASSWORD_FIELD:
154 group = GROUP_PASSWORD;
155 break;
157 case USERNAME_FIELD:
158 group = GROUP_USERNAME;
159 break;
161 case TRANSACTION:
162 NOTREACHED();
163 break;
166 // Interpolate the |metric| with the |group|, so that all metrics for a given
167 // |group| are adjacent.
168 return (group * AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS) + metric;
171 namespace {
173 std::string WalletApiMetricToString(
174 AutofillMetrics::WalletApiCallMetric metric) {
175 switch (metric) {
176 case AutofillMetrics::ACCEPT_LEGAL_DOCUMENTS:
177 return "AcceptLegalDocuments";
178 case AutofillMetrics::AUTHENTICATE_INSTRUMENT:
179 return "AuthenticateInstrument";
180 case AutofillMetrics::GET_FULL_WALLET:
181 return "GetFullWallet";
182 case AutofillMetrics::GET_WALLET_ITEMS:
183 return "GetWalletItems";
184 case AutofillMetrics::SAVE_TO_WALLET:
185 return "SaveToWallet";
186 case AutofillMetrics::UNKNOWN_API_CALL:
187 case AutofillMetrics::NUM_WALLET_API_CALLS:
188 NOTREACHED();
189 return "UnknownApiCall";
192 NOTREACHED();
193 return "UnknownApiCall";
196 // A version of the UMA_HISTOGRAM_ENUMERATION macro that allows the |name|
197 // to vary over the program's runtime.
198 void LogUMAHistogramEnumeration(const std::string& name,
199 int sample,
200 int boundary_value) {
201 DCHECK_LT(sample, boundary_value);
203 // Note: This leaks memory, which is expected behavior.
204 base::HistogramBase* histogram =
205 base::LinearHistogram::FactoryGet(
206 name,
208 boundary_value,
209 boundary_value + 1,
210 base::HistogramBase::kUmaTargetedHistogramFlag);
211 histogram->Add(sample);
214 // A version of the UMA_HISTOGRAM_TIMES macro that allows the |name|
215 // to vary over the program's runtime.
216 void LogUMAHistogramTimes(const std::string& name,
217 const base::TimeDelta& duration) {
218 // Note: This leaks memory, which is expected behavior.
219 base::HistogramBase* histogram =
220 base::Histogram::FactoryTimeGet(
221 name,
222 base::TimeDelta::FromMilliseconds(1),
223 base::TimeDelta::FromSeconds(10),
225 base::HistogramBase::kUmaTargetedHistogramFlag);
226 histogram->AddTime(duration);
229 // A version of the UMA_HISTOGRAM_LONG_TIMES macro that allows the |name|
230 // to vary over the program's runtime.
231 void LogUMAHistogramLongTimes(const std::string& name,
232 const base::TimeDelta& duration) {
233 // Note: This leaks memory, which is expected behavior.
234 base::HistogramBase* histogram =
235 base::Histogram::FactoryTimeGet(
236 name,
237 base::TimeDelta::FromMilliseconds(1),
238 base::TimeDelta::FromHours(1),
240 base::HistogramBase::kUmaTargetedHistogramFlag);
241 histogram->AddTime(duration);
244 // Logs a type quality metric. The primary histogram name is constructed based
245 // on |base_name|. The field-specific histogram name also factors in the
246 // |field_type|. Logs a sample of |metric|, which should be in the range
247 // [0, |num_possible_metrics|).
248 void LogTypeQualityMetric(const std::string& base_name,
249 AutofillMetrics::FieldTypeQualityMetric metric,
250 ServerFieldType field_type) {
251 DCHECK_LT(metric, AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
253 LogUMAHistogramEnumeration(base_name, metric,
254 AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS);
256 int field_type_group_metric = GetFieldTypeGroupMetric(field_type, metric);
257 int num_field_type_group_metrics =
258 AutofillMetrics::NUM_FIELD_TYPE_QUALITY_METRICS *
259 NUM_FIELD_TYPE_GROUPS_FOR_METRICS;
260 LogUMAHistogramEnumeration(base_name + ".ByFieldType",
261 field_type_group_metric,
262 num_field_type_group_metrics);
265 } // namespace
267 // static
268 void AutofillMetrics::LogCreditCardInfoBarMetric(InfoBarMetric metric) {
269 DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
270 UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardInfoBar", metric,
271 NUM_INFO_BAR_METRICS);
274 // static
275 void AutofillMetrics::LogScanCreditCardPromptMetric(
276 ScanCreditCardPromptMetric metric) {
277 DCHECK_LT(metric, NUM_SCAN_CREDIT_CARD_PROMPT_METRICS);
278 UMA_HISTOGRAM_ENUMERATION("Autofill.ScanCreditCardPrompt", metric,
279 NUM_SCAN_CREDIT_CARD_PROMPT_METRICS);
282 // static
283 void AutofillMetrics::LogScanCreditCardCompleted(
284 const base::TimeDelta& duration,
285 bool completed) {
286 std::string suffix = completed ? "Completed" : "Cancelled";
287 LogUMAHistogramLongTimes("Autofill.ScanCreditCard.Duration_" + suffix,
288 duration);
289 UMA_HISTOGRAM_BOOLEAN("Autofill.ScanCreditCard.Completed", completed);
292 // static
293 void AutofillMetrics::LogDialogDismissalState(DialogDismissalState state) {
294 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.DismissalState",
295 state, NUM_DIALOG_DISMISSAL_STATES);
298 // static
299 void AutofillMetrics::LogDialogInitialUserState(
300 DialogInitialUserStateMetric user_type) {
301 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.InitialUserState",
302 user_type, NUM_DIALOG_INITIAL_USER_STATE_METRICS);
305 // static
306 void AutofillMetrics::LogDialogLatencyToShow(const base::TimeDelta& duration) {
307 LogUMAHistogramTimes("RequestAutocomplete.UiLatencyToShow", duration);
310 // static
311 void AutofillMetrics::LogDialogPopupEvent(DialogPopupEvent event) {
312 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.PopupInDialog",
313 event, NUM_DIALOG_POPUP_EVENTS);
316 // static
317 void AutofillMetrics::LogDialogSecurityMetric(DialogSecurityMetric metric) {
318 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.Security",
319 metric, NUM_DIALOG_SECURITY_METRICS);
322 // static
323 void AutofillMetrics::LogDialogUiDuration(
324 const base::TimeDelta& duration,
325 DialogDismissalAction dismissal_action) {
326 std::string suffix;
327 switch (dismissal_action) {
328 case DIALOG_ACCEPTED:
329 suffix = "Submit";
330 break;
332 case DIALOG_CANCELED:
333 suffix = "Cancel";
334 break;
337 LogUMAHistogramLongTimes("RequestAutocomplete.UiDuration", duration);
338 LogUMAHistogramLongTimes("RequestAutocomplete.UiDuration." + suffix,
339 duration);
342 // static
343 void AutofillMetrics::LogDialogUiEvent(DialogUiEvent event) {
344 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.UiEvents", event,
345 NUM_DIALOG_UI_EVENTS);
348 // static
349 void AutofillMetrics::LogUnmaskPromptEvent(UnmaskPromptEvent event) {
350 UMA_HISTOGRAM_ENUMERATION("Autofill.UnmaskPrompt.Events", event,
351 NUM_UNMASK_PROMPT_EVENTS);
354 // static
355 void AutofillMetrics::LogUnmaskPromptEventDuration(
356 const base::TimeDelta& duration,
357 UnmaskPromptEvent close_event) {
358 std::string suffix;
359 switch (close_event) {
360 case UNMASK_PROMPT_CLOSED_NO_ATTEMPTS:
361 suffix = "NoAttempts";
362 break;
363 case UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_RETRIABLE_FAILURE:
364 case UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_NON_RETRIABLE_FAILURE:
365 suffix = "Failure";
366 break;
367 case UNMASK_PROMPT_CLOSED_ABANDON_UNMASKING:
368 suffix = "AbandonUnmasking";
369 break;
370 case UNMASK_PROMPT_UNMASKED_CARD_FIRST_ATTEMPT:
371 case UNMASK_PROMPT_UNMASKED_CARD_AFTER_FAILED_ATTEMPTS:
372 suffix = "Success";
373 break;
374 default:
375 NOTREACHED();
376 return;
378 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.Duration", duration);
379 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.Duration." + suffix,
380 duration);
383 // static
384 void AutofillMetrics::LogTimeBeforeAbandonUnmasking(
385 const base::TimeDelta& duration) {
386 UMA_HISTOGRAM_LONG_TIMES("Autofill.UnmaskPrompt.TimeBeforeAbandonUnmasking",
387 duration);
390 // static
391 void AutofillMetrics::LogRealPanResult(
392 AutofillClient::GetRealPanResult result) {
393 GetRealPanResult metric_result;
394 switch (result) {
395 case AutofillClient::SUCCESS:
396 metric_result = GET_REAL_PAN_RESULT_SUCCESS;
397 break;
398 case AutofillClient::TRY_AGAIN_FAILURE:
399 metric_result = GET_REAL_PAN_RESULT_TRY_AGAIN_FAILURE;
400 break;
401 case AutofillClient::PERMANENT_FAILURE:
402 metric_result = GET_REAL_PAN_RESULT_PERMANENT_FAILURE;
403 break;
404 case AutofillClient::NETWORK_ERROR:
405 metric_result = GET_REAL_PAN_RESULT_NETWORK_ERROR;
406 break;
407 default:
408 NOTREACHED();
409 return;
411 UMA_HISTOGRAM_ENUMERATION("Autofill.UnmaskPrompt.GetRealPanResult",
412 metric_result,
413 NUM_GET_REAL_PAN_RESULTS);
416 // static
417 void AutofillMetrics::LogRealPanDuration(
418 const base::TimeDelta& duration,
419 AutofillClient::GetRealPanResult result) {
420 std::string suffix;
421 switch (result) {
422 case AutofillClient::SUCCESS:
423 suffix = "Success";
424 break;
425 case AutofillClient::TRY_AGAIN_FAILURE:
426 case AutofillClient::PERMANENT_FAILURE:
427 suffix = "Failure";
428 break;
429 case AutofillClient::NETWORK_ERROR:
430 suffix = "NetworkError";
431 break;
432 default:
433 NOTREACHED();
434 return;
436 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.GetRealPanDuration",
437 duration);
438 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.GetRealPanDuration." + suffix,
439 duration);
442 // static
443 void AutofillMetrics::LogUnmaskingDuration(
444 const base::TimeDelta& duration,
445 AutofillClient::GetRealPanResult result) {
446 std::string suffix;
447 switch (result) {
448 case AutofillClient::SUCCESS:
449 suffix = "Success";
450 break;
451 case AutofillClient::TRY_AGAIN_FAILURE:
452 case AutofillClient::PERMANENT_FAILURE:
453 suffix = "Failure";
454 break;
455 case AutofillClient::NETWORK_ERROR:
456 suffix = "NetworkError";
457 break;
458 default:
459 NOTREACHED();
460 return;
462 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.UnmaskingDuration", duration);
463 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.UnmaskingDuration." + suffix,
464 duration);
467 // static
468 void AutofillMetrics::LogWalletErrorMetric(WalletErrorMetric metric) {
469 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.WalletErrors", metric,
470 NUM_WALLET_ERROR_METRICS);
473 // static
474 void AutofillMetrics::LogWalletApiCallDuration(
475 WalletApiCallMetric metric,
476 const base::TimeDelta& duration) {
477 LogUMAHistogramTimes("Wallet.ApiCallDuration." +
478 WalletApiMetricToString(metric), duration);
481 // static
482 void AutofillMetrics::LogWalletMalformedResponseMetric(
483 WalletApiCallMetric metric) {
484 UMA_HISTOGRAM_ENUMERATION("Wallet.MalformedResponse", metric,
485 NUM_WALLET_API_CALLS);
488 // static
489 void AutofillMetrics::LogWalletRequiredActionMetric(
490 WalletRequiredActionMetric required_action) {
491 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.WalletRequiredActions",
492 required_action, NUM_WALLET_REQUIRED_ACTIONS);
495 // static
496 void AutofillMetrics::LogWalletResponseCode(int response_code) {
497 UMA_HISTOGRAM_SPARSE_SLOWLY("Wallet.ResponseCode", response_code);
500 // static
501 void AutofillMetrics::LogDeveloperEngagementMetric(
502 DeveloperEngagementMetric metric) {
503 DCHECK_LT(metric, NUM_DEVELOPER_ENGAGEMENT_METRICS);
504 UMA_HISTOGRAM_ENUMERATION("Autofill.DeveloperEngagement", metric,
505 NUM_DEVELOPER_ENGAGEMENT_METRICS);
508 // static
509 void AutofillMetrics::LogHeuristicTypePrediction(FieldTypeQualityMetric metric,
510 ServerFieldType field_type) {
511 LogTypeQualityMetric("Autofill.Quality.HeuristicType", metric, field_type);
514 // static
515 void AutofillMetrics::LogOverallTypePrediction(FieldTypeQualityMetric metric,
516 ServerFieldType field_type) {
517 LogTypeQualityMetric("Autofill.Quality.PredictedType", metric, field_type);
520 // static
521 void AutofillMetrics::LogServerTypePrediction(FieldTypeQualityMetric metric,
522 ServerFieldType field_type) {
523 LogTypeQualityMetric("Autofill.Quality.ServerType", metric, field_type);
526 // static
527 void AutofillMetrics::LogServerQueryMetric(ServerQueryMetric metric) {
528 DCHECK_LT(metric, NUM_SERVER_QUERY_METRICS);
529 UMA_HISTOGRAM_ENUMERATION("Autofill.ServerQueryResponse", metric,
530 NUM_SERVER_QUERY_METRICS);
533 // static
534 void AutofillMetrics::LogUserHappinessMetric(UserHappinessMetric metric) {
535 DCHECK_LT(metric, NUM_USER_HAPPINESS_METRICS);
536 UMA_HISTOGRAM_ENUMERATION("Autofill.UserHappiness", metric,
537 NUM_USER_HAPPINESS_METRICS);
540 // static
541 void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill(
542 const base::TimeDelta& duration) {
543 UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithAutofill",
544 duration,
545 base::TimeDelta::FromMilliseconds(100),
546 base::TimeDelta::FromMinutes(10),
547 50);
550 // static
551 void AutofillMetrics::LogFormFillDurationFromLoadWithoutAutofill(
552 const base::TimeDelta& duration) {
553 UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithoutAutofill",
554 duration,
555 base::TimeDelta::FromMilliseconds(100),
556 base::TimeDelta::FromMinutes(10),
557 50);
560 // static
561 void AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill(
562 const base::TimeDelta& duration) {
563 UMA_HISTOGRAM_CUSTOM_TIMES(
564 "Autofill.FillDuration.FromInteraction.WithAutofill",
565 duration,
566 base::TimeDelta::FromMilliseconds(100),
567 base::TimeDelta::FromMinutes(10),
568 50);
571 // static
572 void AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill(
573 const base::TimeDelta& duration) {
574 UMA_HISTOGRAM_CUSTOM_TIMES(
575 "Autofill.FillDuration.FromInteraction.WithoutAutofill",
576 duration,
577 base::TimeDelta::FromMilliseconds(100),
578 base::TimeDelta::FromMinutes(10),
579 50);
582 // static
583 void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled) {
584 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled);
587 // static
588 void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(bool enabled) {
589 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.PageLoad", enabled);
592 // static
593 void AutofillMetrics::LogStoredProfileCount(size_t num_profiles) {
594 UMA_HISTOGRAM_COUNTS("Autofill.StoredProfileCount", num_profiles);
597 // static
598 void AutofillMetrics::LogNumberOfProfilesAtAutofillableFormSubmission(
599 size_t num_profiles) {
600 UMA_HISTOGRAM_COUNTS(
601 "Autofill.StoredProfileCountAtAutofillableFormSubmission", num_profiles);
604 // static
605 void AutofillMetrics::LogAddressSuggestionsCount(size_t num_suggestions) {
606 UMA_HISTOGRAM_COUNTS("Autofill.AddressSuggestionsCount", num_suggestions);
609 void AutofillMetrics::LogPasswordFormQueryVolume(
610 PasswordFormQueryVolumeMetric metric) {
611 UMA_HISTOGRAM_ENUMERATION("Autofill.PasswordFormQueryVolume", metric,
612 NUM_PASSWORD_FORM_QUERY_VOLUME_METRIC);
615 AutofillMetrics::FormEventLogger::FormEventLogger(bool is_for_credit_card)
616 : is_for_credit_card_(is_for_credit_card),
617 is_server_data_available_(false),
618 is_local_data_available_(false),
619 has_logged_interacted_(false),
620 has_logged_suggestions_shown_(false),
621 has_logged_masked_server_card_suggestion_selected_(false),
622 has_logged_suggestion_filled_(false),
623 has_logged_will_submit_(false),
624 has_logged_submitted_(false),
625 logged_suggestion_filled_was_server_data_(false),
626 logged_suggestion_filled_was_masked_server_card_(false) {
629 void AutofillMetrics::FormEventLogger::OnDidInteractWithAutofillableForm() {
630 if (!has_logged_interacted_) {
631 has_logged_interacted_ = true;
632 Log(AutofillMetrics::FORM_EVENT_INTERACTED_ONCE);
636 void AutofillMetrics::FormEventLogger::OnDidShowSuggestions() {
637 Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN);
638 if (!has_logged_suggestions_shown_) {
639 has_logged_suggestions_shown_ = true;
640 Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN_ONCE);
644 void AutofillMetrics::FormEventLogger::OnDidSelectMaskedServerCardSuggestion() {
645 DCHECK(is_for_credit_card_);
646 Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED);
647 if (!has_logged_masked_server_card_suggestion_selected_) {
648 has_logged_masked_server_card_suggestion_selected_ = true;
649 Log(AutofillMetrics
650 ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE);
654 void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
655 const CreditCard& credit_card) {
656 DCHECK(is_for_credit_card_);
657 if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD)
658 Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED);
659 else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD)
660 Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED);
661 else
662 Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED);
664 if (!has_logged_suggestion_filled_) {
665 has_logged_suggestion_filled_ = true;
666 logged_suggestion_filled_was_server_data_ =
667 credit_card.record_type() == CreditCard::MASKED_SERVER_CARD ||
668 credit_card.record_type() == CreditCard::FULL_SERVER_CARD;
669 logged_suggestion_filled_was_masked_server_card_ =
670 credit_card.record_type() == CreditCard::MASKED_SERVER_CARD;
671 if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD) {
672 Log(AutofillMetrics
673 ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE);
674 } else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD) {
675 Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE);
676 } else {
677 Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
682 void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
683 const AutofillProfile& profile) {
684 DCHECK(!is_for_credit_card_);
685 if (profile.record_type() == AutofillProfile::SERVER_PROFILE)
686 Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED);
687 else
688 Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED);
690 if (!has_logged_suggestion_filled_) {
691 has_logged_suggestion_filled_ = true;
692 logged_suggestion_filled_was_server_data_ =
693 profile.record_type() == AutofillProfile::SERVER_PROFILE;
694 Log(profile.record_type() == AutofillProfile::SERVER_PROFILE
695 ? AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
696 : AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
700 void AutofillMetrics::FormEventLogger::OnWillSubmitForm() {
701 // Not logging this kind of form if we haven't logged a user interaction.
702 if (!has_logged_interacted_)
703 return;
705 // Not logging twice.
706 if (has_logged_will_submit_)
707 return;
708 has_logged_will_submit_ = true;
710 if (!has_logged_suggestion_filled_) {
711 Log(AutofillMetrics::FORM_EVENT_NO_SUGGESTION_WILL_SUBMIT_ONCE);
712 } else if (logged_suggestion_filled_was_masked_server_card_) {
713 Log(AutofillMetrics::
714 FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_WILL_SUBMIT_ONCE);
715 } else if (logged_suggestion_filled_was_server_data_) {
716 Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_WILL_SUBMIT_ONCE);
717 } else {
718 Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_WILL_SUBMIT_ONCE);
722 void AutofillMetrics::FormEventLogger::OnFormSubmitted() {
723 // Not logging this kind of form if we haven't logged a user interaction.
724 if (!has_logged_interacted_)
725 return;
727 // Not logging twice.
728 if (has_logged_submitted_)
729 return;
730 has_logged_submitted_ = true;
732 if (!has_logged_suggestion_filled_) {
733 Log(AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE);
734 } else if (logged_suggestion_filled_was_masked_server_card_) {
735 Log(AutofillMetrics
736 ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE);
737 } else if (logged_suggestion_filled_was_server_data_) {
738 Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE);
739 } else {
740 Log(AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_SUBMITTED_ONCE);
744 void AutofillMetrics::FormEventLogger::Log(FormEvent event) const {
745 DCHECK_LT(event, NUM_FORM_EVENTS);
746 std::string name("Autofill.FormEvents.");
747 if (is_for_credit_card_)
748 name += "CreditCard";
749 else
750 name += "Address";
751 LogUMAHistogramEnumeration(name, event, NUM_FORM_EVENTS);
753 // Logging again in a different histogram for segmentation purposes.
754 // TODO(waltercacau): Re-evaluate if we still need such fine grained
755 // segmentation. http://crbug.com/454018
756 if (!is_server_data_available_ && !is_local_data_available_)
757 name += ".WithNoData";
758 else if (is_server_data_available_ && !is_local_data_available_)
759 name += ".WithOnlyServerData";
760 else if (!is_server_data_available_ && is_local_data_available_)
761 name += ".WithOnlyLocalData";
762 else
763 name += ".WithBothServerAndLocalData";
764 LogUMAHistogramEnumeration(name, event, NUM_FORM_EVENTS);
767 } // namespace autofill