diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc index 5820625afe12fc..88882ff93d5a8a 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator.cc @@ -154,7 +154,8 @@ AutofillSuggestionGenerator::GetSuggestionsForCreditCards( std::u16string field_contents_lower = base::i18n::ToLower(field_contents); - metadata_logging_context = GetMetadataLoggingContext(cards_to_suggest); + metadata_logging_context = + autofill_metrics::GetMetadataLoggingContext(cards_to_suggest); // Set `should_display_gpay_logo` to true if all cards are server cards, and // to false if any of the card is a local card. @@ -718,46 +719,6 @@ void AutofillSuggestionGenerator::SetCardArtURL( #endif } -autofill_metrics::CardMetadataLoggingContext -AutofillSuggestionGenerator::GetMetadataLoggingContext( - const std::vector& cards_to_suggest) const { - bool card_product_description_available = false; - bool card_art_image_available = false; - bool virtual_card_with_card_art_image = false; - - for (const auto* card : cards_to_suggest) { - if (!card->product_description().empty()) - card_product_description_available = true; - - if (card->card_art_url().is_valid()) { - card_art_image_available = true; - if (card->virtual_card_enrollment_state() == - CreditCard::VirtualCardEnrollmentState::ENROLLED) { - virtual_card_with_card_art_image = true; - } - } - } - - autofill_metrics::CardMetadataLoggingContext metadata_logging_context; - metadata_logging_context.card_metadata_available = - card_product_description_available || card_art_image_available; - - metadata_logging_context.card_product_description_shown = - card_product_description_available && - base::FeatureList::IsEnabled(features::kAutofillEnableCardProductName); - - // `card_art_image_shown` is set to true if art image is available and - // 1. the experiment is enabled or - // 2. the card with art image has a linked virtual card (for virtual cards, - // the card art image is always shown if available). - metadata_logging_context.card_art_image_shown = - card_art_image_available && - (base::FeatureList::IsEnabled(features::kAutofillEnableCardArtImage) || - virtual_card_with_card_art_image); - - return metadata_logging_context; -} - InternalId AutofillSuggestionGenerator::BackendIdToInternalId( const Suggestion::BackendId& backend_id) { if (!base::IsValidGUID(*backend_id)) diff --git a/components/autofill/core/browser/autofill_suggestion_generator.h b/components/autofill/core/browser/autofill_suggestion_generator.h index 24bfb161591667..8d1ad13002b624 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.h +++ b/components/autofill/core/browser/autofill_suggestion_generator.h @@ -177,11 +177,6 @@ class AutofillSuggestionGenerator { const CreditCard& credit_card, bool virtual_card_option) const; - // Return the CardMetadataLoggingContext based on the credit cards - // to be shown in the suggestion. - autofill_metrics::CardMetadataLoggingContext GetMetadataLoggingContext( - const std::vector& cards_to_suggest) const; - // Maps suggestion backend ID to and from an internal ID identifying it. Two // of these intermediate internal IDs are packed by MakeFrontendID to make the // IDs that this class generates for the UI and for IPC. diff --git a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc index bafc1fb5a5fb6b..b94cfb67b65ef9 100644 --- a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc @@ -6186,6 +6186,7 @@ TEST_P(AutofillMetricsTestForCardMetadata, LogCardMetadataMetrics) { CreditCard masked_server_card = test::GetMaskedServerCard(); masked_server_card.set_guid(kTestMaskedCardId); + masked_server_card.set_issuer_id("amex"); if (card_metadata_available()) { masked_server_card.set_product_description(u"card_description"); masked_server_card.set_card_art_url( @@ -6208,30 +6209,40 @@ TEST_P(AutofillMetricsTestForCardMetadata, LogCardMetadataMetrics) { mojom::RendererFormDataAction::kFill, form, form.fields.front(), MakeFrontendId({.credit_card_id = kTestMaskedCardId})); - std::string histogram_prefix = - "Autofill.CreditCard.SuggestionAcceptanceLatencySinceShown"; - std::string histogram_name = histogram_prefix; + std::string latency_histogram_prefix = + "Autofill.CreditCard.SelectionLatencySinceShown"; + + std::string latency_histogram_suffix; if (card_metadata_available()) { // Verify the suggestion acceptance latency was logged when metadata was // available or the suggestions had one virtual card. if (card_product_name_enabled() && (card_art_image_enabled() || card_has_linked_virtual_card())) { - histogram_name += ".ProductDescriptionAndArtImageShown"; + latency_histogram_suffix = + autofill_metrics::kProductNameAndArtImageBothShownSuffix; } else if (card_product_name_enabled()) { - histogram_name += ".ProductDescriptionShown"; + latency_histogram_suffix = autofill_metrics::kProductNameShownOnlySuffix; } else if (card_art_image_enabled() || card_has_linked_virtual_card()) { - histogram_name += ".ArtImageShown"; + latency_histogram_suffix = autofill_metrics::kArtImageShownOnlySuffix; } else { - histogram_name += ".MetadataNotShown"; + latency_histogram_suffix = + autofill_metrics::kProductNameAndArtImageNotShownSuffix; } - EXPECT_THAT(histogram_tester.GetTotalCountsForPrefix(histogram_prefix), - ElementsAre(testing::Pair(histogram_name, 1))); - histogram_tester.ExpectUniqueSample(histogram_name, 2000, 1); + + histogram_tester.ExpectUniqueSample(latency_histogram_prefix + + ".AnyCardWithMetadata" + + latency_histogram_suffix, + 2000, 1); + histogram_tester.ExpectUniqueSample(latency_histogram_prefix + + ".SelectedCardWithMetadata" + + latency_histogram_suffix + ".Amex", + 2000, 1); } else { // Verify that no histogram should be logged when metadata was not // available and the suggestions had no virtual card. EXPECT_TRUE( - histogram_tester.GetTotalCountsForPrefix(histogram_prefix).empty()); + histogram_tester.GetTotalCountsForPrefix(latency_histogram_prefix) + .empty()); } } diff --git a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc index 4db792db47f296..85498a83ca30d0 100644 --- a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc +++ b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc @@ -105,13 +105,9 @@ void CreditCardFormEventLogger::OnDidSelectCardSuggestion( break; } - // Log the latency between suggestion being shown and suggestion being - // selected. - if (metadata_logging_context_.card_metadata_available) { - autofill_metrics::LogCardSuggestionAcceptanceLatencyMetric( - AutofillTickClock::NowTicks() - suggestion_shown_timestamp_, - metadata_logging_context_); - } + autofill_metrics::LogAcceptanceLatency( + AutofillTickClock::NowTicks() - suggestion_shown_timestamp_, + metadata_logging_context_, credit_card); } void CreditCardFormEventLogger::OnDidFillSuggestion( diff --git a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc index 52840a0b6cb2cb..7f7d118b2baa4b 100644 --- a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc +++ b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.cc @@ -5,25 +5,106 @@ #include "components/autofill/core/browser/metrics/payments/card_metadata_metrics.h" #include "base/metrics/histogram_functions.h" +#include "components/autofill/core/common/autofill_payments_features.h" namespace autofill::autofill_metrics { -void LogCardSuggestionAcceptanceLatencyMetric( - base::TimeDelta latency, - const CardMetadataLoggingContext& context) { - std::string histogram_name = - "Autofill.CreditCard.SuggestionAcceptanceLatencySinceShown"; - - if (context.card_product_description_shown && context.card_art_image_shown) - histogram_name += ".ProductDescriptionAndArtImageShown"; - else if (context.card_product_description_shown) - histogram_name += ".ProductDescriptionShown"; - else if (context.card_art_image_shown) - histogram_name += ".ArtImageShown"; - else - histogram_name += ".MetadataNotShown"; - - base::UmaHistogramMediumTimes(histogram_name, latency); +namespace { +std::string GetHistogramSuffix(const CardMetadataLoggingContext& context) { + if (context.card_product_description_shown && context.card_art_image_shown) { + return kProductNameAndArtImageBothShownSuffix; + } + + if (context.card_product_description_shown) { + return kProductNameShownOnlySuffix; + } + + if (context.card_art_image_shown) { + return kArtImageShownOnlySuffix; + } + + return kProductNameAndArtImageNotShownSuffix; +} +} // namespace + +CardMetadataLoggingContext GetMetadataLoggingContext( + const std::vector& cards) { + bool card_product_description_available = false; + bool card_art_image_available = false; + bool virtual_card_with_card_art_image = false; + + for (const auto* card : cards) { + if (!card->product_description().empty()) { + card_product_description_available = true; + } + + if (card->card_art_url().is_valid()) { + card_art_image_available = true; + if (card->virtual_card_enrollment_state() == + CreditCard::VirtualCardEnrollmentState::ENROLLED) { + virtual_card_with_card_art_image = true; + } + } + } + + autofill_metrics::CardMetadataLoggingContext metadata_logging_context; + metadata_logging_context.card_metadata_available = + card_product_description_available || card_art_image_available; + + metadata_logging_context.card_product_description_shown = + card_product_description_available && + base::FeatureList::IsEnabled(features::kAutofillEnableCardProductName); + + // `card_art_image_shown` is set to true if art image is available and + // 1. the experiment is enabled or + // 2. the card with art image has a linked virtual card (for virtual cards, + // the card art image is always shown if available). + metadata_logging_context.card_art_image_shown = + card_art_image_available && + (base::FeatureList::IsEnabled(features::kAutofillEnableCardArtImage) || + virtual_card_with_card_art_image); + + return metadata_logging_context; +} + +void LogAcceptanceLatency(base::TimeDelta latency, + const CardMetadataLoggingContext& suggestion_context, + const CreditCard& selected_card) { + if (!suggestion_context.card_metadata_available) { + return; + } + std::string histogram_name_prefix = + "Autofill.CreditCard.SelectionLatencySinceShown"; + base::UmaHistogramMediumTimes(histogram_name_prefix + ".AnyCardWithMetadata" + + GetHistogramSuffix(suggestion_context), + latency); + + CreditCard duplicate = selected_card; + auto selected_card_context = GetMetadataLoggingContext({&duplicate}); + if (!selected_card_context.card_metadata_available) { + return; + } + + base::UmaHistogramMediumTimes(histogram_name_prefix + + ".SelectedCardWithMetadata" + + GetHistogramSuffix(selected_card_context), + latency); + + if (!selected_card.issuer_id().empty()) { + std::string issuer_id_string; + if (selected_card.issuer_id() == "amex") { + issuer_id_string = kAmericanExpress; + } else if (selected_card.issuer_id() == "capitalone") { + issuer_id_string = kCapitalOne; + } else { + NOTREACHED() << "Update logic when adding new issuers."; + return; + } + base::UmaHistogramMediumTimes( + histogram_name_prefix + ".SelectedCardWithMetadata" + + GetHistogramSuffix(selected_card_context) + "." + issuer_id_string, + latency); + } } } // namespace autofill::autofill_metrics diff --git a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.h b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.h index 142fd848a8fb75..246f27d503ddbb 100644 --- a/components/autofill/core/browser/metrics/payments/card_metadata_metrics.h +++ b/components/autofill/core/browser/metrics/payments/card_metadata_metrics.h @@ -9,6 +9,15 @@ namespace autofill::autofill_metrics { +constexpr char kAmericanExpress[] = "Amex"; +constexpr char kCapitalOne[] = "CapitalOne"; + +constexpr char kProductNameAndArtImageBothShownSuffix[] = + ".ProductDescriptionAndArtImageShown"; +constexpr char kProductNameShownOnlySuffix[] = ".ProductDescriptionShown"; +constexpr char kArtImageShownOnlySuffix[] = ".ArtImageShown"; +constexpr char kProductNameAndArtImageNotShownSuffix[] = ".MetadataNotShown"; + // Struct that groups some metadata related information together. Used for // metrics logging. struct CardMetadataLoggingContext { @@ -17,12 +26,15 @@ struct CardMetadataLoggingContext { bool card_art_image_shown = false; }; +// Get the CardMetadataLoggingContext for the given credit cards. +CardMetadataLoggingContext GetMetadataLoggingContext( + const std::vector& cards); + // Log the latency between suggestions being shown and a suggestion was -// selected, in milliseconds. Only logged when at least one card in the -// suggestion list has available card metadata. -void LogCardSuggestionAcceptanceLatencyMetric( - base::TimeDelta latency, - const CardMetadataLoggingContext& context); +// selected, in milliseconds. +void LogAcceptanceLatency(base::TimeDelta latency, + const CardMetadataLoggingContext& suggestion_context, + const CreditCard& selected_card); } // namespace autofill::autofill_metrics diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index 8ba00894c6c98a..be6c6b099d8cc9 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml @@ -53,6 +53,20 @@ chromium-metrics-reviews@google.com. summary="OTP fallback from FIDO authentication"/> + + + + + + + + + + + + @@ -1037,25 +1051,59 @@ chromium-metrics-reviews@google.com. + siyua@chromium.org + payments-autofill-team@google.com + + The latency between Autofill credit card suggestion dropdown being shown, + and when a suggestion was selected, in milliseconds. Logged immediately when + a card suggestion is selected by the user, on the condition that any card + (not necessarily the selected card) in the suggestion list has card metadata + available (even if the metadata is not shown). This helps identify whether + showing the card metadata has potential impact on assisting card selection + in general. + + + + + siyua@chromium.org payments-autofill-team@google.com The latency between an Autofill credit card suggestion being shown, and when it was selected, in milliseconds. Logged immediately when a card is selected - by the user, on the condition that any card (not necessarily the selected - card) in the suggestion list has card metadata available (even if the - metadata is not shown). - - - - - - - + by the user, on the condition that the selected card has card metadata + available (even if the metadata is not shown). This is also broken down by + card issuer id if it is available. This helps identify whether showing the + card metadata has potential impact on latency for selecting a particular + card. + + + + + + + + Deprecated 01/23 and replaced by + Autofill.CreditCard.SelectionLatencySinceShown.AnyCardWithMetadata.{CardMetadataVisible}. + + siyua@chromium.org + payments-autofill-team@google.com + + The latency between Autofill credit card suggestion dropdown being shown, + and when a suggestion was selected, in milliseconds. Logged immediately when + a card suggestion is selected by the user, on the condition that any card + (not necessarily the selected card) in the suggestion list has card metadata + available (even if the metadata is not shown). This helps identify whether + showing the card metadata has potential impact on assisting card selection + in general. + +