Skip to content

Commit

Permalink
[Metadata] Add issuer breakdown for latency metrics
Browse files Browse the repository at this point in the history
This issuer id will be static and passed down from the server side. Currently we have only "amex", and "capitalone" planned.

Bug: 1313616
Change-Id: I939bb566245b6ac20ce0a01dfdb30f948e078554
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4119257
Reviewed-by: Florian Leimgruber <fleimgruber@google.com>
Reviewed-by: Vidhan Jain <vidhanj@google.com>
Commit-Queue: Siyu An <siyua@chromium.org>
Reviewed-by: Vishwas Uppoor <vishwasuppoor@google.com>
Reviewed-by: Vinny Persky <vinnypersky@google.com>
Cr-Commit-Position: refs/heads/main@{#1098195}
  • Loading branch information
Siyu An authored and Chromium LUCI CQ committed Jan 28, 2023
1 parent 0072dcd commit 0cf623f
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 98 deletions.
43 changes: 2 additions & 41 deletions components/autofill/core/browser/autofill_suggestion_generator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -718,46 +719,6 @@ void AutofillSuggestionGenerator::SetCardArtURL(
#endif
}

autofill_metrics::CardMetadataLoggingContext
AutofillSuggestionGenerator::GetMetadataLoggingContext(
const std::vector<CreditCard*>& 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))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<CreditCard*>& 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<CreditCard*>& 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
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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<CreditCard*>& 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

Expand Down
74 changes: 61 additions & 13 deletions tools/metrics/histograms/metadata/autofill/histograms.xml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ chromium-metrics-reviews@google.com.
summary="OTP fallback from FIDO authentication"/>
</variants>

<variants name="Autofill.CardMetadataVisible">
<variant name="ArtImageShown" summary="Only art image was visible"/>
<variant name="MetadataNotShown" summary="No metadata was visible"/>
<variant name="ProductDescriptionAndArtImageShown"
summary="Both product description and art image were visible"/>
<variant name="ProductDescriptionShown"
summary="Only product description was visible"/>
</variants>

<variants name="Autofill.CreditCardIssuerId">
<variant name=".Amex" summary="American Express."/>
<variant name=".CapitalOne" summary="Capital One."/>
</variants>

<variants name="Autofill.DialogError">
<variant name="WithNoTemporaryError"
summary="No temporary error has been shown in the dialog"/>
Expand Down Expand Up @@ -1037,25 +1051,59 @@ chromium-metrics-reviews@google.com.
</histogram>

<histogram
name="Autofill.CreditCard.SuggestionAcceptanceLatencySinceShown.{CardMetadataVisible}"
name="Autofill.CreditCard.SelectionLatencySinceShown.AnyCardWithMetadata.{CardMetadataVisible}"
units="ms" expires_after="2023-05-01">
<owner>siyua@chromium.org</owner>
<owner>payments-autofill-team@google.com</owner>
<summary>
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.
</summary>
<token key="CardMetadataVisible" variants="Autofill.CardMetadataVisible"/>
</histogram>

<histogram
name="Autofill.CreditCard.SelectionLatencySinceShown.SelectedCardWithMetadata.{CardMetadataVisible}{CardIssuerId}"
units="ms" expires_after="2023-05-01">
<owner>siyua@chromium.org</owner>
<owner>payments-autofill-team@google.com</owner>
<summary>
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).
</summary>
<token key="CardMetadataVisible">
<variant name="ArtImageShown" summary="Only art image was visible"/>
<variant name="MetadataNotShown" summary="No metadata was visible"/>
<variant name="ProductDescriptionAndArtImageShown"
summary="Both product description and art image were visible"/>
<variant name="ProductDescriptionShown"
summary="Only product description was visible"/>
</token>
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.
</summary>
<token key="CardMetadataVisible" variants="Autofill.CardMetadataVisible"/>
<token key="CardIssuerId" variants="Autofill.CreditCardIssuerId"/>
</histogram>

<histogram
name="Autofill.CreditCard.SuggestionAcceptanceLatencySinceShown.{CardMetadataVisible}"
units="ms" expires_after="2023-05-01">
<obsolete>
Deprecated 01/23 and replaced by
Autofill.CreditCard.SelectionLatencySinceShown.AnyCardWithMetadata.{CardMetadataVisible}.
</obsolete>
<owner>siyua@chromium.org</owner>
<owner>payments-autofill-team@google.com</owner>
<summary>
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.
</summary>
<token key="CardMetadataVisible" variants="Autofill.CardMetadataVisible"/>
</histogram>

<histogram name="Autofill.CreditCardFillingInfoBar"
Expand Down

0 comments on commit 0cf623f

Please sign in to comment.