Commit 085d2f35 authored by Jared Saul's avatar Jared Saul Committed by Commit Bot

[Autofill] Allow for blocking Elo/JCB cards from credit card upload

Bug: 868552
Change-Id: Iac64b875611994439dae09d65ff7c999cde74ff8
Reviewed-on: https://chromium-review.googlesource.com/1153301Reviewed-by: default avatarRobert Kaplow (slow) <rkaplow@chromium.org>
Reviewed-by: default avatarSebastien Seguin-Gagnon <sebsg@chromium.org>
Commit-Queue: Jared Saul <jsaul@google.com>
Cr-Commit-Position: refs/heads/master@{#579908}
parent ed751be8
......@@ -659,6 +659,22 @@ void AutofillMetrics::LogSubmittedServerCardExpirationStatusMetric(
NUM_SUBMITTED_SERVER_CARD_EXPIRATION_STATUS_METRICS);
}
// static
void AutofillMetrics::LogUploadDisallowedForNetworkMetric(
const std::string& network) {
UploadDisallowedForNetworkMetric metric;
if (network == kEloCard) {
metric = DISALLOWED_ELO;
} else if (network == kJCBCard) {
metric = DISALLOWED_JCB;
} else {
NOTREACHED();
return;
}
UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardUploadDisallowedForNetwork",
metric);
}
// static
void AutofillMetrics::LogUploadOfferedCardOriginMetric(
UploadOfferedCardOriginMetric metric) {
......
......@@ -156,6 +156,14 @@ class AutofillMetrics {
NUM_SUBMITTED_SERVER_CARD_EXPIRATION_STATUS_METRICS,
};
// Metric to measure volume of cards that are disallowed for upload by their
// network, most likely due to their network being blocked by Google Payments.
enum UploadDisallowedForNetworkMetric {
DISALLOWED_ELO = 0,
DISALLOWED_JCB = 1,
kMaxValue = DISALLOWED_JCB,
};
// Metric to measure if a card for which upload was offered is already stored
// as a local card on the device or if it has not yet been seen.
enum UploadOfferedCardOriginMetric {
......@@ -781,6 +789,10 @@ class AutofillMetrics {
static void LogSubmittedServerCardExpirationStatusMetric(
SubmittedServerCardExpirationStatusMetric metric);
// When credit card upload is disallowed for a particular network, logs which
// network was blocked.
static void LogUploadDisallowedForNetworkMetric(const std::string& network);
// When credit card upload is offered, logs whether the card being offered is
// already a local card on the device or not.
static void LogUploadOfferedCardOriginMetric(
......
......@@ -192,6 +192,19 @@ bool CreditCardSaveManager::IsCreditCardUploadEnabled() {
client_->GetIdentityManager()->GetPrimaryAccountInfo().email);
}
bool CreditCardSaveManager::IsUploadEnabledForNetwork(
const std::string& network) {
if (network == kEloCard &&
base::FeatureList::IsEnabled(features::kAutofillUpstreamDisallowElo)) {
return false;
} else if (network == kJCBCard &&
base::FeatureList::IsEnabled(
features::kAutofillUpstreamDisallowJcb)) {
return false;
}
return true;
}
void CreditCardSaveManager::OnDidUploadCard(
AutofillClient::PaymentsRpcResult result,
const std::string& server_id) {
......
......@@ -96,6 +96,11 @@ class CreditCardSaveManager {
// are satisfied.
virtual bool IsCreditCardUploadEnabled();
// Returns true if the given |network| is allowed for upload to Google
// Payments, false otherwise. Mainly used for blacklisting upload of certain
// networks.
bool IsUploadEnabledForNetwork(const std::string& network);
// For testing.
void SetAppLocale(std::string app_locale) { app_locale_ = app_locale; }
......
......@@ -69,6 +69,9 @@ using UkmDeveloperEngagementType = ukm::builders::Autofill_DeveloperEngagement;
const base::Time kArbitraryTime = base::Time::FromDoubleT(25);
const base::Time kMuchLaterTime = base::Time::FromDoubleT(5000);
const char kEloCardNumber[] = "5067111111111112";
const char kJcbCardNumber[] = "3528111111111110";
std::string NextYear() {
base::Time::Exploded now;
base::Time::Now().LocalExplode(&now);
......@@ -3592,4 +3595,173 @@ TEST_F(CreditCardSaveManagerTest, UploadCreditCard_UploadOfNewCard) {
AutofillMetrics::USER_ACCEPTED_UPLOAD_OF_NEW_CARD, 1);
}
TEST_F(CreditCardSaveManagerTest, UploadCreditCard_EloDisallowed) {
personal_data_.ClearProfiles();
credit_card_save_manager_->SetCreditCardUploadEnabled(true);
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamDisallowElo);
// Set up our credit card form data.
FormData credit_card_form;
CreateTestCreditCardFormData(&credit_card_form, true, false);
FormsSeen(std::vector<FormData>(1, credit_card_form));
// Edit the data, and submit.
credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
credit_card_form.fields[1].value = ASCIIToUTF16(kEloCardNumber);
credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
credit_card_form.fields[4].value = ASCIIToUTF16("123");
base::HistogramTester histogram_tester;
// With Elo disallowed, local save should be offered and upload save should
// not.
EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _));
FormSubmitted(credit_card_form);
EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
// Verify that the correct histogram entry was logged.
histogram_tester.ExpectUniqueSample(
"Autofill.CreditCardUploadDisallowedForNetwork",
AutofillMetrics::DISALLOWED_ELO, 1);
}
TEST_F(CreditCardSaveManagerTest, UploadCreditCard_EloAllowed) {
personal_data_.ClearProfiles();
credit_card_save_manager_->SetCreditCardUploadEnabled(true);
scoped_feature_list_.InitAndDisableFeature(
features::kAutofillUpstreamDisallowElo);
// Set up our credit card form data.
FormData credit_card_form;
CreateTestCreditCardFormData(&credit_card_form, true, false);
FormsSeen(std::vector<FormData>(1, credit_card_form));
// Edit the data, and submit.
credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
credit_card_form.fields[1].value = ASCIIToUTF16(kEloCardNumber);
credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
credit_card_form.fields[4].value = ASCIIToUTF16("123");
base::HistogramTester histogram_tester;
// With the feature flag off, the Elo card should be allowed to be uploaded as
// normal.
EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
FormSubmitted(credit_card_form);
EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
// Verify that no histogram entry was logged.
histogram_tester.ExpectTotalCount(
"Autofill.CreditCardUploadDisallowedForNetwork", 0);
}
TEST_F(CreditCardSaveManagerTest, UploadCreditCard_JcbDisallowed) {
personal_data_.ClearProfiles();
credit_card_save_manager_->SetCreditCardUploadEnabled(true);
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamDisallowJcb);
// Set up our credit card form data.
FormData credit_card_form;
CreateTestCreditCardFormData(&credit_card_form, true, false);
FormsSeen(std::vector<FormData>(1, credit_card_form));
// Edit the data, and submit.
credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
credit_card_form.fields[1].value = ASCIIToUTF16(kJcbCardNumber);
credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
credit_card_form.fields[4].value = ASCIIToUTF16("123");
base::HistogramTester histogram_tester;
// With JCB disallowed, local save should be offered and upload save should
// not.
EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _));
FormSubmitted(credit_card_form);
EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
// Verify that the correct histogram entry was logged.
histogram_tester.ExpectUniqueSample(
"Autofill.CreditCardUploadDisallowedForNetwork",
AutofillMetrics::DISALLOWED_JCB, 1);
}
TEST_F(CreditCardSaveManagerTest, UploadCreditCard_JcbAllowed) {
personal_data_.ClearProfiles();
credit_card_save_manager_->SetCreditCardUploadEnabled(true);
scoped_feature_list_.InitAndDisableFeature(
features::kAutofillUpstreamDisallowJcb);
// Set up our credit card form data.
FormData credit_card_form;
CreateTestCreditCardFormData(&credit_card_form, true, false);
FormsSeen(std::vector<FormData>(1, credit_card_form));
// Edit the data, and submit.
credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
credit_card_form.fields[1].value = ASCIIToUTF16(kJcbCardNumber);
credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
credit_card_form.fields[4].value = ASCIIToUTF16("123");
base::HistogramTester histogram_tester;
// With the feature flag off, the JCB card should be allowed to be uploaded as
// normal.
EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
FormSubmitted(credit_card_form);
EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded());
// Verify that no histogram entry was logged.
histogram_tester.ExpectTotalCount(
"Autofill.CreditCardUploadDisallowedForNetwork", 0);
}
// We can't tell what network a card is until *after* FormDataImporter imports
// it, making it possible to deny upload save for a pre-existing local card.
// This test ensures that we do not offer local save (again) for the card that
// FormDataImporter imported.
TEST_F(CreditCardSaveManagerTest, UploadCreditCard_DisallowedLocalCard) {
personal_data_.ClearProfiles();
credit_card_save_manager_->SetCreditCardUploadEnabled(true);
scoped_feature_list_.InitAndEnableFeature(
features::kAutofillUpstreamDisallowElo);
// Add a local credit card that will match what we will enter below.
CreditCard local_card;
test::SetCreditCardInfo(&local_card, "Flo Master", kEloCardNumber,
NextMonth().c_str(), NextYear().c_str(), "1");
local_card.set_record_type(CreditCard::LOCAL_CARD);
personal_data_.AddCreditCard(local_card);
// Set up our credit card form data.
FormData credit_card_form;
CreateTestCreditCardFormData(&credit_card_form, true, false);
FormsSeen(std::vector<FormData>(1, credit_card_form));
// Edit the data, and submit.
credit_card_form.fields[0].value = ASCIIToUTF16("Flo Master");
credit_card_form.fields[1].value = ASCIIToUTF16(kEloCardNumber);
credit_card_form.fields[2].value = ASCIIToUTF16(NextMonth());
credit_card_form.fields[3].value = ASCIIToUTF16(NextYear());
credit_card_form.fields[4].value = ASCIIToUTF16("123");
base::HistogramTester histogram_tester;
// The card is disallowed, but because it is already a local card, local save
// should not be offered again.
EXPECT_CALL(autofill_client_, ConfirmSaveCreditCardLocally(_, _)).Times(0);
FormSubmitted(credit_card_form);
EXPECT_FALSE(credit_card_save_manager_->CreditCardWasUploaded());
// Verify that the correct histogram entry was logged.
histogram_tester.ExpectUniqueSample(
"Autofill.CreditCardUploadDisallowedForNetwork",
AutofillMetrics::DISALLOWED_ELO, 1);
}
} // namespace autofill
......@@ -147,6 +147,21 @@ void FormDataImporter::ImportFormData(const FormStructure& submitted_form,
if (!imported_credit_card)
return;
// Check if the imported card is from a network that is currently disallowed,
// often due to Google Payments not accepting a certain card network. If so,
// don't offer to upload the card. We can fall back to local save as long as
// it's a new card instead of an existing local card.
if (!credit_card_save_manager_->IsUploadEnabledForNetwork(
imported_credit_card->network())) {
is_credit_card_upstream_enabled = false;
AutofillMetrics::LogUploadDisallowedForNetworkMetric(
imported_credit_card->network());
if (imported_credit_card_record_type_ ==
ImportedCreditCardRecordType::LOCAL_CARD) {
return;
}
}
// We have a card to save; decide what type of save flow to display.
if (is_credit_card_upstream_enabled) {
// Attempt to offer upload save. Because we pass
......
......@@ -119,6 +119,14 @@ const base::Feature kAutofillShowTypePredictions{
const base::Feature kAutofillSkipComparingInferredLabels{
"AutofillSkipComparingInferredLabels", base::FEATURE_DISABLED_BY_DEFAULT};
// Controls whether ELO cards should be uploaded to Google Payments.
const base::Feature kAutofillUpstreamDisallowElo{
"AutofillUpstreamDisallowElo", base::FEATURE_DISABLED_BY_DEFAULT};
// Controls whether JCB cards should be uploaded to Google Payments.
const base::Feature kAutofillUpstreamDisallowJcb{
"AutofillUpstreamDisallowJcb", base::FEATURE_DISABLED_BY_DEFAULT};
// Controls whether the credit card upload bubble shows the Google Pay logo and
// a shorter "Save card?" header message on mobile.
const base::Feature kAutofillUpstreamUseGooglePayBrandingOnMobile{
......
......@@ -30,6 +30,8 @@ extern const base::Feature kAutofillShowAllSuggestionsOnPrefilledForms;
extern const base::Feature kAutofillShowAutocompleteConsoleWarnings;
extern const base::Feature kAutofillShowTypePredictions;
extern const base::Feature kAutofillSkipComparingInferredLabels;
extern const base::Feature kAutofillUpstreamDisallowElo;
extern const base::Feature kAutofillUpstreamDisallowJcb;
extern const base::Feature kAutofillUpstreamUseGooglePayBrandingOnMobile;
extern const base::Feature kAutomaticPasswordGeneration;
extern const base::Feature kSingleClickAutofill;
......
......@@ -8386,6 +8386,11 @@ Called by update_net_error_codes.py.-->
<int value="8" label="Auto sign-in"/>
</enum>
<enum name="CreditCardUploadDisallowedNetwork">
<int value="0" label="Elo card"/>
<int value="1" label="JCB card"/>
</enum>
<enum name="CrosBeamformingDeviceState">
<int value="0" label="Default enabled"/>
<int value="1" label="User enabled"/>
......@@ -6356,6 +6356,15 @@ uploading your change for review.
</summary>
</histogram>
<histogram name="Autofill.CreditCardUploadDisallowedForNetwork"
enum="CreditCardUploadDisallowedNetwork">
<owner>jsaul@google.com</owner>
<summary>
When a credit card is not allowed to be offered upload save due to its
network, logs what the card network was.
</summary>
</histogram>
<histogram name="Autofill.DaysSinceLastUse.CreditCard" units="days">
<owner>sebsg@chromium.org</owner>
<summary>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment