| Index: components/autofill/core/browser/personal_data_manager.cc
|
| diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
|
| index 4c00de1bc4d4ec159d73747e3bcf57f3fd82ddef..ca700932942c19cfeb0b54804d33e976f2460145 100644
|
| --- a/components/autofill/core/browser/personal_data_manager.cc
|
| +++ b/components/autofill/core/browser/personal_data_manager.cc
|
| @@ -442,13 +442,16 @@ void PersonalDataManager::RemoveObserver(
|
| bool PersonalDataManager::ImportFormData(
|
| const FormStructure& form,
|
| bool should_return_local_card,
|
| - std::unique_ptr<CreditCard>* imported_credit_card) {
|
| + std::unique_ptr<CreditCard>* imported_credit_card,
|
| + bool* imported_credit_card_matches_masked_server_credit_card) {
|
| // We try the same |form| for both credit card and address import/update.
|
| // - ImportCreditCard may update an existing card, or fill
|
| // |imported_credit_card| with an extracted card. See .h for details of
|
| - // |should_return_local_card|.
|
| + // |should_return_local_card| and
|
| + // |imported_credit_card_matches_masked_server_credit_card|.
|
| bool cc_import =
|
| - ImportCreditCard(form, should_return_local_card, imported_credit_card);
|
| + ImportCreditCard(form, should_return_local_card, imported_credit_card,
|
| + imported_credit_card_matches_masked_server_credit_card);
|
| // - ImportAddressProfiles may eventually save or update one or more address
|
| // profiles.
|
| bool address_import = ImportAddressProfiles(form);
|
| @@ -1497,8 +1500,10 @@ bool PersonalDataManager::ImportAddressProfileForSection(
|
| bool PersonalDataManager::ImportCreditCard(
|
| const FormStructure& form,
|
| bool should_return_local_card,
|
| - std::unique_ptr<CreditCard>* imported_credit_card) {
|
| + std::unique_ptr<CreditCard>* imported_credit_card,
|
| + bool* imported_credit_card_matches_masked_server_credit_card) {
|
| DCHECK(!imported_credit_card->get());
|
| + *imported_credit_card_matches_masked_server_credit_card = false;
|
|
|
| // The candidate for credit card import. There are many ways for the candidate
|
| // to be rejected (see everywhere this function returns false, below).
|
| @@ -1561,7 +1566,8 @@ bool PersonalDataManager::ImportCreditCard(
|
| // have already saved this card number, unless |should_return_local_card| is
|
| // true which indicates that upload is enabled. In this case, it's useful to
|
| // present the upload prompt to the user to promote the card from a local card
|
| - // to a synced server card.
|
| + // to a synced server card, provided we don't have a masked server card with
|
| + // the same |TypeAndLastFourDigits|.
|
| for (const auto& card : local_credit_cards_) {
|
| // Make a local copy so that the data in |local_credit_cards_| isn't
|
| // modified directly by the UpdateFromImportedCard() call.
|
| @@ -1578,14 +1584,22 @@ bool PersonalDataManager::ImportCreditCard(
|
| }
|
| }
|
|
|
| - // Also don't offer to save if we already have this stored as a server card.
|
| - // We only check the number because if the new card has the same number as the
|
| - // server card, upload is guaranteed to fail. There's no mechanism for entries
|
| - // with the same number but different names or expiration dates as there is
|
| - // for local cards.
|
| + // Also don't offer to save if we already have this stored as a full server
|
| + // card. We only check the number because if the new card has the same number
|
| + // as the server card, upload is guaranteed to fail. There's no mechanism for
|
| + // entries with the same number but different names or expiration dates as
|
| + // there is for local cards.
|
| + // We can offer to save locally even if we already have this stored another
|
| + // masked server card with the same |TypeAndLastFourDigits| so that the user
|
| + // can enter the full card number without having to unmask the card.
|
| for (const auto& card : server_credit_cards_) {
|
| - if (candidate_credit_card.HasSameNumberAs(*card))
|
| - return false;
|
| + if (candidate_credit_card.HasSameNumberAs(*card)) {
|
| + if (card->record_type() == CreditCard::FULL_SERVER_CARD)
|
| + return false;
|
| + DCHECK_EQ(card->record_type(), CreditCard::MASKED_SERVER_CARD);
|
| + *imported_credit_card_matches_masked_server_credit_card = true;
|
| + break;
|
| + }
|
| }
|
|
|
| imported_credit_card->reset(new CreditCard(candidate_credit_card));
|
|
|