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"
19 enum FieldTypeGroupForMetrics
{
28 GROUP_ADDRESS_COUNTRY
,
30 GROUP_FAX
, // Deprecated.
32 GROUP_CREDIT_CARD_NAME
,
33 GROUP_CREDIT_CARD_NUMBER
,
34 GROUP_CREDIT_CARD_DATE
,
35 GROUP_CREDIT_CARD_TYPE
,
39 NUM_FIELD_TYPE_GROUPS_FOR_METRICS
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:
56 // AMBIGUOUS+MISMATCH,
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
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()) {
76 group
= GROUP_AMBIGUOUS
;
85 group
= GROUP_COMPANY
;
90 switch (AutofillType(field_type
).GetStorableType()) {
91 case ADDRESS_HOME_LINE1
:
92 group
= GROUP_ADDRESS_LINE_1
;
94 case ADDRESS_HOME_LINE2
:
95 group
= GROUP_ADDRESS_LINE_2
;
97 case ADDRESS_HOME_LINE3
:
98 group
= GROUP_ADDRESS_LINE_3
;
100 case ADDRESS_HOME_CITY
:
101 group
= GROUP_ADDRESS_CITY
;
103 case ADDRESS_HOME_STATE
:
104 group
= GROUP_ADDRESS_STATE
;
106 case ADDRESS_HOME_ZIP
:
107 group
= GROUP_ADDRESS_ZIP
;
109 case ADDRESS_HOME_COUNTRY
:
110 group
= GROUP_ADDRESS_COUNTRY
;
114 group
= GROUP_AMBIGUOUS
;
129 switch (field_type
) {
130 case CREDIT_CARD_NAME
:
131 group
= GROUP_CREDIT_CARD_NAME
;
133 case CREDIT_CARD_NUMBER
:
134 group
= GROUP_CREDIT_CARD_NUMBER
;
136 case CREDIT_CARD_TYPE
:
137 group
= GROUP_CREDIT_CARD_TYPE
;
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
;
148 group
= GROUP_AMBIGUOUS
;
154 group
= GROUP_PASSWORD
;
158 group
= GROUP_USERNAME
;
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
;
173 std::string
WalletApiMetricToString(
174 AutofillMetrics::WalletApiCallMetric 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
:
189 return "UnknownApiCall";
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
,
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(
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(
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(
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
);
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
);
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
);
283 void AutofillMetrics::LogScanCreditCardCompleted(
284 const base::TimeDelta
& duration
,
286 std::string suffix
= completed
? "Completed" : "Cancelled";
287 LogUMAHistogramLongTimes("Autofill.ScanCreditCard.Duration_" + suffix
,
289 UMA_HISTOGRAM_BOOLEAN("Autofill.ScanCreditCard.Completed", completed
);
293 void AutofillMetrics::LogDialogDismissalState(DialogDismissalState state
) {
294 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.DismissalState",
295 state
, NUM_DIALOG_DISMISSAL_STATES
);
299 void AutofillMetrics::LogDialogInitialUserState(
300 DialogInitialUserStateMetric user_type
) {
301 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.InitialUserState",
302 user_type
, NUM_DIALOG_INITIAL_USER_STATE_METRICS
);
306 void AutofillMetrics::LogDialogLatencyToShow(const base::TimeDelta
& duration
) {
307 LogUMAHistogramTimes("RequestAutocomplete.UiLatencyToShow", duration
);
311 void AutofillMetrics::LogDialogPopupEvent(DialogPopupEvent event
) {
312 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.PopupInDialog",
313 event
, NUM_DIALOG_POPUP_EVENTS
);
317 void AutofillMetrics::LogDialogSecurityMetric(DialogSecurityMetric metric
) {
318 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.Security",
319 metric
, NUM_DIALOG_SECURITY_METRICS
);
323 void AutofillMetrics::LogDialogUiDuration(
324 const base::TimeDelta
& duration
,
325 DialogDismissalAction dismissal_action
) {
327 switch (dismissal_action
) {
328 case DIALOG_ACCEPTED
:
332 case DIALOG_CANCELED
:
337 LogUMAHistogramLongTimes("RequestAutocomplete.UiDuration", duration
);
338 LogUMAHistogramLongTimes("RequestAutocomplete.UiDuration." + suffix
,
343 void AutofillMetrics::LogDialogUiEvent(DialogUiEvent event
) {
344 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.UiEvents", event
,
345 NUM_DIALOG_UI_EVENTS
);
349 void AutofillMetrics::LogUnmaskPromptEvent(UnmaskPromptEvent event
) {
350 UMA_HISTOGRAM_ENUMERATION("Autofill.UnmaskPrompt.Events", event
,
351 NUM_UNMASK_PROMPT_EVENTS
);
355 void AutofillMetrics::LogUnmaskPromptEventDuration(
356 const base::TimeDelta
& duration
,
357 UnmaskPromptEvent close_event
) {
359 switch (close_event
) {
360 case UNMASK_PROMPT_CLOSED_NO_ATTEMPTS
:
361 suffix
= "NoAttempts";
363 case UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_RETRIABLE_FAILURE
:
364 case UNMASK_PROMPT_CLOSED_FAILED_TO_UNMASK_NON_RETRIABLE_FAILURE
:
367 case UNMASK_PROMPT_CLOSED_ABANDON_UNMASKING
:
368 suffix
= "AbandonUnmasking";
370 case UNMASK_PROMPT_UNMASKED_CARD_FIRST_ATTEMPT
:
371 case UNMASK_PROMPT_UNMASKED_CARD_AFTER_FAILED_ATTEMPTS
:
378 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.Duration", duration
);
379 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.Duration." + suffix
,
384 void AutofillMetrics::LogTimeBeforeAbandonUnmasking(
385 const base::TimeDelta
& duration
) {
386 UMA_HISTOGRAM_LONG_TIMES("Autofill.UnmaskPrompt.TimeBeforeAbandonUnmasking",
391 void AutofillMetrics::LogRealPanResult(
392 AutofillClient::GetRealPanResult result
) {
393 GetRealPanResult metric_result
;
395 case AutofillClient::SUCCESS
:
396 metric_result
= GET_REAL_PAN_RESULT_SUCCESS
;
398 case AutofillClient::TRY_AGAIN_FAILURE
:
399 metric_result
= GET_REAL_PAN_RESULT_TRY_AGAIN_FAILURE
;
401 case AutofillClient::PERMANENT_FAILURE
:
402 metric_result
= GET_REAL_PAN_RESULT_PERMANENT_FAILURE
;
404 case AutofillClient::NETWORK_ERROR
:
405 metric_result
= GET_REAL_PAN_RESULT_NETWORK_ERROR
;
411 UMA_HISTOGRAM_ENUMERATION("Autofill.UnmaskPrompt.GetRealPanResult",
413 NUM_GET_REAL_PAN_RESULTS
);
417 void AutofillMetrics::LogRealPanDuration(
418 const base::TimeDelta
& duration
,
419 AutofillClient::GetRealPanResult result
) {
422 case AutofillClient::SUCCESS
:
425 case AutofillClient::TRY_AGAIN_FAILURE
:
426 case AutofillClient::PERMANENT_FAILURE
:
429 case AutofillClient::NETWORK_ERROR
:
430 suffix
= "NetworkError";
436 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.GetRealPanDuration",
438 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.GetRealPanDuration." + suffix
,
443 void AutofillMetrics::LogUnmaskingDuration(
444 const base::TimeDelta
& duration
,
445 AutofillClient::GetRealPanResult result
) {
448 case AutofillClient::SUCCESS
:
451 case AutofillClient::TRY_AGAIN_FAILURE
:
452 case AutofillClient::PERMANENT_FAILURE
:
455 case AutofillClient::NETWORK_ERROR
:
456 suffix
= "NetworkError";
462 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.UnmaskingDuration", duration
);
463 LogUMAHistogramLongTimes("Autofill.UnmaskPrompt.UnmaskingDuration." + suffix
,
468 void AutofillMetrics::LogWalletErrorMetric(WalletErrorMetric metric
) {
469 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.WalletErrors", metric
,
470 NUM_WALLET_ERROR_METRICS
);
474 void AutofillMetrics::LogWalletApiCallDuration(
475 WalletApiCallMetric metric
,
476 const base::TimeDelta
& duration
) {
477 LogUMAHistogramTimes("Wallet.ApiCallDuration." +
478 WalletApiMetricToString(metric
), duration
);
482 void AutofillMetrics::LogWalletMalformedResponseMetric(
483 WalletApiCallMetric metric
) {
484 UMA_HISTOGRAM_ENUMERATION("Wallet.MalformedResponse", metric
,
485 NUM_WALLET_API_CALLS
);
489 void AutofillMetrics::LogWalletRequiredActionMetric(
490 WalletRequiredActionMetric required_action
) {
491 UMA_HISTOGRAM_ENUMERATION("RequestAutocomplete.WalletRequiredActions",
492 required_action
, NUM_WALLET_REQUIRED_ACTIONS
);
496 void AutofillMetrics::LogWalletResponseCode(int response_code
) {
497 UMA_HISTOGRAM_SPARSE_SLOWLY("Wallet.ResponseCode", response_code
);
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
);
509 void AutofillMetrics::LogHeuristicTypePrediction(FieldTypeQualityMetric metric
,
510 ServerFieldType field_type
) {
511 LogTypeQualityMetric("Autofill.Quality.HeuristicType", metric
, field_type
);
515 void AutofillMetrics::LogOverallTypePrediction(FieldTypeQualityMetric metric
,
516 ServerFieldType field_type
) {
517 LogTypeQualityMetric("Autofill.Quality.PredictedType", metric
, field_type
);
521 void AutofillMetrics::LogServerTypePrediction(FieldTypeQualityMetric metric
,
522 ServerFieldType field_type
) {
523 LogTypeQualityMetric("Autofill.Quality.ServerType", metric
, field_type
);
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
);
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
);
541 void AutofillMetrics::LogFormFillDurationFromLoadWithAutofill(
542 const base::TimeDelta
& duration
) {
543 UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithAutofill",
545 base::TimeDelta::FromMilliseconds(100),
546 base::TimeDelta::FromMinutes(10),
551 void AutofillMetrics::LogFormFillDurationFromLoadWithoutAutofill(
552 const base::TimeDelta
& duration
) {
553 UMA_HISTOGRAM_CUSTOM_TIMES("Autofill.FillDuration.FromLoad.WithoutAutofill",
555 base::TimeDelta::FromMilliseconds(100),
556 base::TimeDelta::FromMinutes(10),
561 void AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill(
562 const base::TimeDelta
& duration
) {
563 UMA_HISTOGRAM_CUSTOM_TIMES(
564 "Autofill.FillDuration.FromInteraction.WithAutofill",
566 base::TimeDelta::FromMilliseconds(100),
567 base::TimeDelta::FromMinutes(10),
572 void AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill(
573 const base::TimeDelta
& duration
) {
574 UMA_HISTOGRAM_CUSTOM_TIMES(
575 "Autofill.FillDuration.FromInteraction.WithoutAutofill",
577 base::TimeDelta::FromMilliseconds(100),
578 base::TimeDelta::FromMinutes(10),
583 void AutofillMetrics::LogIsAutofillEnabledAtStartup(bool enabled
) {
584 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.Startup", enabled
);
588 void AutofillMetrics::LogIsAutofillEnabledAtPageLoad(bool enabled
) {
589 UMA_HISTOGRAM_BOOLEAN("Autofill.IsEnabled.PageLoad", enabled
);
593 void AutofillMetrics::LogStoredProfileCount(size_t num_profiles
) {
594 UMA_HISTOGRAM_COUNTS("Autofill.StoredProfileCount", num_profiles
);
598 void AutofillMetrics::LogNumberOfProfilesAtAutofillableFormSubmission(
599 size_t num_profiles
) {
600 UMA_HISTOGRAM_COUNTS(
601 "Autofill.StoredProfileCountAtAutofillableFormSubmission", num_profiles
);
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;
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
);
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
) {
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
);
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
);
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_
)
705 // Not logging twice.
706 if (has_logged_will_submit_
)
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
);
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_
)
727 // Not logging twice.
728 if (has_logged_submitted_
)
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_
) {
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
);
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";
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";
763 name
+= ".WithBothServerAndLocalData";
764 LogUMAHistogramEnumeration(name
, event
, NUM_FORM_EVENTS
);
767 } // namespace autofill