| // Copyright 2017 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_MANAGER_H_ |
| #define COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_MANAGER_H_ |
| |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/optional.h" |
| #include "base/strings/string16.h" |
| #include "build/build_config.h" |
| #include "components/autofill/core/browser/autofill_client.h" |
| #include "components/autofill/core/browser/autofill_metrics.h" |
| #include "components/autofill/core/browser/credit_card.h" |
| #include "components/autofill/core/browser/credit_card_save_strike_database.h" |
| #include "components/autofill/core/browser/form_structure.h" |
| #include "components/autofill/core/browser/payments/payments_client.h" |
| #include "components/autofill/core/browser/personal_data_manager.h" |
| #include "url/origin.h" |
| |
| namespace autofill { |
| |
| // Manages logic for determining whether upload credit card save to Google |
| // Payments is available as well as actioning both local and upload credit card |
| // save logic. Owned by FormDataImporter. |
| class CreditCardSaveManager { |
| public: |
| // Possible fields and values detected during credit card form submission, to |
| // be sent to Google Payments to better determine if upload credit card save |
| // should be offered. These should stay consistent with the equivalent enum |
| // in Google Payments code. |
| enum DetectedValue { |
| // Set if a valid CVC was detected. Will always be set if the CVC fix flow |
| // is enabled. |
| CVC = 1 << 0, |
| // Set if a cardholder name was found, *unless* conflicting names were |
| // found. |
| CARDHOLDER_NAME = 1 << 1, |
| // Set if an address name was found, *unless* conflicting names were found. |
| ADDRESS_NAME = 1 << 2, |
| // Set if an address line was found in any address (regardless of |
| // conflicts). |
| ADDRESS_LINE = 1 << 3, |
| // Set if a locality was found in any address (regardless of conflicts). |
| LOCALITY = 1 << 4, |
| // Set if an administrative area was found in any address (regardless of |
| // conflicts). |
| ADMINISTRATIVE_AREA = 1 << 5, |
| // Set if a postal code was found in any address, *unless* conflicting |
| // postal codes were found. |
| POSTAL_CODE = 1 << 6, |
| // Set if a country code was found in any address (regardless of conflicts). |
| COUNTRY_CODE = 1 << 7, |
| // Set if the user is already syncing data from a Google Payments account. |
| HAS_GOOGLE_PAYMENTS_ACCOUNT = 1 << 8, |
| // Card expiration month. |
| CARD_EXPIRATION_MONTH = 1 << 9, |
| // Card expiration year. |
| CARD_EXPIRATION_YEAR = 1 << 10, |
| // Phone number was found on any address (not currently used). |
| PHONE_NUMBER = 1 << 11, |
| // Set if cardholder name was explicitly requested in the offer-to-save |
| // dialog. In general, this should happen when name is conflicting/missing |
| // and the user does not have a Google Payments account. |
| USER_PROVIDED_NAME = 1 << 12, |
| // Set if expiration date was explicitly requested in the offer-to-save |
| // dialog. In general, this should happen when expiration date month or year |
| // is missing. |
| USER_PROVIDED_EXPIRATION_DATE = 1 << 13, |
| }; |
| |
| // An observer class used by browsertests that gets notified whenever |
| // particular actions occur. |
| class ObserverForTest { |
| public: |
| virtual void OnOfferLocalSave() = 0; |
| virtual void OnDecideToRequestUploadSave() = 0; |
| virtual void OnReceivedGetUploadDetailsResponse() = 0; |
| virtual void OnSentUploadCardRequest() = 0; |
| virtual void OnReceivedUploadCardResponse() = 0; |
| virtual void OnStrikeChangeComplete() = 0; |
| }; |
| |
| // The parameters should outlive the CreditCardSaveManager. |
| CreditCardSaveManager(AutofillClient* client, |
| payments::PaymentsClient* payments_client, |
| const std::string& app_locale, |
| PersonalDataManager* personal_data_manager); |
| virtual ~CreditCardSaveManager(); |
| |
| // Begins the process to offer local credit card save to the user. |
| void AttemptToOfferCardLocalSave(const CreditCard& card); |
| |
| // Begins the process to offer upload credit card save to the user if the |
| // imported card passes all requirements and Google Payments approves. |
| void AttemptToOfferCardUploadSave(const FormStructure& submitted_form, |
| const CreditCard& card, |
| const bool uploading_local_card); |
| |
| // Returns true if all the conditions for enabling the upload of credit card |
| // 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; } |
| |
| protected: |
| // Returns the result of an upload request. If |result| == |
| // |AutofillClient::SUCCESS|, clears strikes for the saved card. Additionally, |
| // |server_id| may, optionally, contain the opaque identifier for the card on |
| // the server. Exposed for testing. |
| virtual void OnDidUploadCard(AutofillClient::PaymentsRpcResult result, |
| const std::string& server_id); |
| |
| private: |
| friend class CreditCardSaveManagerTest; |
| friend class CreditCardSaveManagerTestObserverBridge; |
| friend class TestCreditCardSaveManager; |
| friend class SaveCardBubbleViewsFullFormBrowserTest; |
| |
| // Returns the CreditCardSaveStrikeDatabase for |client_|. |
| CreditCardSaveStrikeDatabase* GetCreditCardSaveStrikeDatabase(); |
| |
| // Sets |show_save_prompt| and moves forward with offering credit card local |
| // save. |
| void OnDidGetStrikesForLocalSave(const int num_strikes); |
| |
| // Sets |show_save_prompt| and moves forward with offering credit card upload |
| // if Payments has also returned a success response. |
| void OnDidGetStrikesForUploadSave(const int num_strikes); |
| |
| // Returns the legal message retrieved from Payments. On failure or not |
| // meeting Payments's conditions for upload, |legal_message| will contain |
| // nullptr. |
| void OnDidGetUploadDetails(AutofillClient::PaymentsRpcResult result, |
| const base::string16& context_token, |
| std::unique_ptr<base::Value> legal_message); |
| |
| // Logs the number of strikes that a card had when save succeeded. |
| void LogStrikesPresentWhenCardSaved(bool is_local, const int num_strikes); |
| |
| // Examines |card| and the stored profiles and if a candidate set of profiles |
| // is found that matches the client-side validation rules, assigns the values |
| // to |upload_request.profiles|. If any problems are found when determining |
| // the candidate set of profiles, sets |upload_decision_metrics_| with the |
| // failure reasons. Appends any experiments that were triggered to |
| // |upload_request.active_experiments|. Note that if the relevant feature is |
| // enabled, the addresses being assigned to |upload_request.profiles| may only |
| // contain countries. |
| void SetProfilesForCreditCardUpload( |
| const CreditCard& card, |
| payments::PaymentsClient::UploadRequestDetails* upload_request); |
| |
| // Analyzes the decisions made while importing address profile and credit card |
| // data in preparation for upload credit card save, in order to determine what |
| // uploadable data is actually available. |
| int GetDetectedValues() const; |
| |
| // Offers local credit card save once the Autofill StrikeSystem has made its |
| // decision. |
| void OfferCardLocalSave(); |
| |
| // Offers credit card upload if Payments has allowed offering to save and the |
| // Autofill StrikeSystem has made its decision. |
| void OfferCardUploadSave(); |
| |
| // Called once the user makes a decision with respect to the local credit card |
| // offer-to-save prompt. If accepted, clears strikes for the to-be-saved card |
| // and has |personal_data_manager_| save the card. |
| void OnUserDidDecideOnLocalSave( |
| AutofillClient::SaveCardOfferUserDecision user_decision); |
| |
| // Called once the user makes a decision with respect to the credit card |
| // upload offer-to-save prompt. |
| // If accepted: |
| // Sets |user_did_accept_upload_prompt_| and calls SendUploadCardRequest if |
| // the risk data is available. Sets the cardholder name on the upload |
| // request if |user_provided_card_details.cardholder_name| is set. Sets the |
| // expiration date on the upload request if |
| // |user_provided_card_details.expiration_date_month| and |
| // |user_provided_card_details.expiration_date_year| are both set. |
| // If rejected or ignored: |
| // Logs a strike against the current card to deter future offers to save. |
| void OnUserDidDecideOnUploadSave( |
| AutofillClient::SaveCardOfferUserDecision user_decision, |
| const AutofillClient::UserProvidedCardDetails& |
| user_provided_card_details); |
| |
| #if defined(OS_ANDROID) |
| // Sets |user_did_accept_upload_prompt_| and calls SendUploadCardRequest if |
| // the risk data is available. Sets the cardholder name on the upload request |
| // if |cardholder_name| is set. |
| // Only relevant for mobile as fix flow is two steps on mobile compared to |
| // one step on desktop. |
| void OnUserDidAcceptAccountNameFixFlow(const base::string16& cardholder_name); |
| #endif // defined(OS_ANDROID) |
| |
| // Helper function that calls SendUploadCardRequest by setting |
| // UserProvidedCardDetails. |
| void OnUserDidAcceptUploadHelper( |
| const AutofillClient::UserProvidedCardDetails& |
| user_provided_card_details); |
| |
| // Saves risk data in |uploading_risk_data_| and calls SendUploadCardRequest |
| // if the user has accepted the prompt. |
| void OnDidGetUploadRiskData(const std::string& risk_data); |
| |
| // Finalizes the upload request and calls PaymentsClient::UploadCard(). |
| void SendUploadCardRequest(); |
| |
| // Called when the user ignored or declined the credit card save prompt. Logs |
| // a strike for the given card in order to help deter future offers to save, |
| // provided that save was actually offered to the user. |
| void OnUserDidIgnoreOrDeclineSave( |
| const base::string16& card_last_four_digits); |
| |
| // Used for browsertests. Gives the |observer_for_testing_| a notification |
| // a strike change has been made. |
| void OnStrikeChangeComplete(const int num_strikes); |
| |
| // Returns metric relevant to the CVC field based on values in |
| // |found_cvc_field_|, |found_value_in_cvc_field_| and |
| // |found_cvc_value_in_non_cvc_field_|. Only called when a valid CVC was NOT |
| // found. |
| AutofillMetrics::CardUploadDecisionMetric GetCVCCardUploadDecisionMetric() |
| const; |
| |
| // Logs the card upload decisions in UKM and UMA. |
| // |upload_decision_metrics| is a bitmask of |
| // |AutofillMetrics::CardUploadDecisionMetric|. |
| void LogCardUploadDecisions(int upload_decision_metrics); |
| |
| // Logs the reason why expiration date was explicitly requested. |
| void LogSaveCardRequestExpirationDateReasonMetric(); |
| |
| // For testing. |
| void SetEventObserverForTesting(ObserverForTest* observer) { |
| observer_for_testing_ = observer; |
| } |
| |
| AutofillClient* const client_; |
| |
| // Handles Payments service requests. |
| // Owned by AutofillManager. |
| payments::PaymentsClient* payments_client_; |
| |
| std::string app_locale_; |
| |
| // The personal data manager, used to save and load personal data to/from the |
| // web database. This is overridden by the AutofillManagerTest. |
| // Weak reference. |
| // May be NULL. NULL indicates OTR. |
| PersonalDataManager* personal_data_manager_; |
| |
| // The credit card to be saved if local credit card save is accepted. |
| CreditCard local_card_save_candidate_; |
| |
| // Collected information about a pending upload request. |
| payments::PaymentsClient::UploadRequestDetails upload_request_; |
| |
| // A bitmask of |AutofillMetrics::CardUploadDecisionMetric| representing the |
| // decisions made when determining if credit card upload save should be |
| // offered. |
| int upload_decision_metrics_ = 0; |
| |
| // |true| if the offer-to-save bubble/infobar should pop-up, |false| if not. |
| // Will be base::nullopt until data has been retrieved from the StrikeSystem. |
| base::Optional<bool> show_save_prompt_; |
| |
| // |true| if the card being offered for upload is already a local card on the |
| // device; |false| otherwise. |
| bool uploading_local_card_ = false; |
| |
| // |true| if the user has opted to upload save their credit card to Google. |
| bool user_did_accept_upload_prompt_ = false; |
| |
| // |should_request_expiration_date_from_user_| is |true| if the upload save |
| // dialog should request expiration date from the user. |
| bool should_request_expiration_date_from_user_ = false; |
| |
| // |should_request_name_from_user_| is |true| if the upload save dialog should |
| // request cardholder name from the user (prefilled with Google Account name). |
| bool should_request_name_from_user_ = false; |
| |
| // |found_cvc_field_| is |true| if there exists a field that is determined to |
| // be a CVC field via heuristics. |
| bool found_cvc_field_ = false; |
| // |found_value_in_cvc_field_| is |true| if a field that is determined to |
| // be a CVC field via heuristics has non-empty |value|. |
| // |value| may or may not be a valid CVC. |
| bool found_value_in_cvc_field_ = false; |
| // |found_cvc_value_in_non_cvc_field_| is |true| if a field that is not |
| // determined to be a CVC field via heuristics has a valid CVC |value|. |
| bool found_cvc_value_in_non_cvc_field_ = false; |
| |
| // The origin of the top level frame from which a form is uploaded. |
| url::Origin pending_upload_request_origin_; |
| |
| // The returned legal message from a GetUploadDetails call to Google Payments. |
| std::unique_ptr<base::DictionaryValue> legal_message_; |
| |
| std::unique_ptr<CreditCardSaveStrikeDatabase> strike_database_; |
| |
| // May be null. |
| ObserverForTest* observer_for_testing_ = nullptr; |
| |
| base::WeakPtrFactory<CreditCardSaveManager> weak_ptr_factory_; |
| |
| FRIEND_TEST_ALL_PREFIXES( |
| CreditCardSaveManagerTest, |
| UploadCreditCard_ShouldRequestCardholderName_ResetBetweenConsecutiveSaves); |
| FRIEND_TEST_ALL_PREFIXES( |
| CreditCardSaveManagerTest, |
| UploadCreditCard_ShouldRequestExpirationDate_ResetBetweenConsecutiveSaves); |
| |
| DISALLOW_COPY_AND_ASSIGN(CreditCardSaveManager); |
| }; |
| |
| } // namespace autofill |
| |
| #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_CREDIT_CARD_SAVE_MANAGER_H_ |