blob: c9f385fcd566b6ceca2ef6f9731ac49f97b10c39 [file] [log] [blame]
// Copyright 2013 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_AUTOFILL_MANAGER_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_MANAGER_H_
#include <list>
#include <map>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string16.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autocomplete_history_manager.h"
#include "components/autofill/core/browser/autofill_client.h"
#include "components/autofill/core/browser/autofill_download_manager.h"
#include "components/autofill/core/browser/autofill_driver.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/card_unmask_delegate.h"
#include "components/autofill/core/browser/form_structure.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/wallet/real_pan_wallet_client.h"
#include "components/autofill/core/common/form_data.h"
// This define protects some debugging code (see DumpAutofillData). This
// is here to make it easier to delete this code when the test is complete,
// and to prevent adding the code on mobile where there is no desktop (the
// debug dump file is written to the desktop) or command-line flags to enable.
#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)
#define ENABLE_FORM_DEBUG_DUMP
#endif
class ChromeUIWebViewWebTest;
class ChromeWKWebViewWebTest;
namespace gfx {
class Rect;
class RectF;
}
namespace user_prefs {
class PrefRegistrySyncable;
}
namespace autofill {
class AutofillDataModel;
class AutofillDownloadManager;
class AutofillExternalDelegate;
class AutofillField;
class AutofillClient;
class AutofillManagerTestDelegate;
class AutofillProfile;
class AutofillType;
class CreditCard;
class FormStructureBrowserTest;
template <class WebTestT> class FormStructureBrowserTestIos;
struct FormData;
struct FormFieldData;
// Manages saving and restoring the user's personal information entered into web
// forms. One per frame; owned by the AutofillDriver.
class AutofillManager : public AutofillDownloadManager::Observer,
public CardUnmaskDelegate,
public wallet::RealPanWalletClient::Delegate {
public:
enum AutofillDownloadManagerState {
ENABLE_AUTOFILL_DOWNLOAD_MANAGER,
DISABLE_AUTOFILL_DOWNLOAD_MANAGER,
};
// Registers our Enable/Disable Autofill pref.
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
AutofillManager(AutofillDriver* driver,
AutofillClient* client,
const std::string& app_locale,
AutofillDownloadManagerState enable_download_manager);
~AutofillManager() override;
// Sets an external delegate.
void SetExternalDelegate(AutofillExternalDelegate* delegate);
void ShowAutofillSettings();
// Whether the |field| should show an entry to scan a credit card.
virtual bool ShouldShowScanCreditCard(const FormData& form,
const FormFieldData& field);
// Called from our external delegate so they cannot be private.
virtual void FillOrPreviewForm(AutofillDriver::RendererFormDataAction action,
int query_id,
const FormData& form,
const FormFieldData& field,
int unique_id);
virtual void FillCreditCardForm(int query_id,
const FormData& form,
const FormFieldData& field,
const CreditCard& credit_card);
void DidShowSuggestions(bool is_new_popup,
const FormData& form,
const FormFieldData& field);
void OnDidFillAutofillFormData(const base::TimeTicks& timestamp);
void OnDidPreviewAutofillFormData();
// Returns true if the value/identifier is deletable. Fills out
// |title| and |body| with relevant user-facing text.
bool GetDeletionConfirmationText(const base::string16& value,
int identifier,
base::string16* title,
base::string16* body);
// Remove the credit card or Autofill profile that matches |unique_id|
// from the database. Returns true if deletion is allowed.
bool RemoveAutofillProfileOrCreditCard(int unique_id);
// Remove the specified Autocomplete entry.
void RemoveAutocompleteEntry(const base::string16& name,
const base::string16& value);
// Returns true when the Wallet card unmask prompt is being displayed.
bool IsShowingUnmaskPrompt();
// Returns the present form structures seen by Autofill manager.
const std::vector<FormStructure*>& GetFormStructures();
// Happens when the autocomplete dialog runs its callback when being closed.
void RequestAutocompleteDialogClosed();
AutofillClient* client() const { return client_; }
const std::string& app_locale() const { return app_locale_; }
// Only for testing.
void SetTestDelegate(AutofillManagerTestDelegate* delegate);
void OnFormsSeen(const std::vector<FormData>& forms,
const base::TimeTicks& timestamp);
// IMPORTANT: On iOS, this method is called when the form is submitted,
// immediately before OnFormSubmitted() is called. Do not assume that
// OnWillSubmitForm() will run before the form submits.
// TODO(mathp): Revisit this and use a single method to track form submission.
//
// Processes the about-to-be-submitted |form|, uploading the possible field
// types for the submitted fields to the crowdsourcing server. Returns false
// if this form is not relevant for Autofill.
bool OnWillSubmitForm(const FormData& form, const base::TimeTicks& timestamp);
// Processes the submitted |form|, saving any new Autofill data to the user's
// personal profile. Returns false if this form is not relevant for Autofill.
bool OnFormSubmitted(const FormData& form);
void OnTextFieldDidChange(const FormData& form,
const FormFieldData& field,
const base::TimeTicks& timestamp);
// The |bounding_box| is a window relative value.
void OnQueryFormFieldAutofill(int query_id,
const FormData& form,
const FormFieldData& field,
const gfx::RectF& bounding_box);
void OnDidEndTextFieldEditing();
void OnHidePopup();
void OnSetDataList(const std::vector<base::string16>& values,
const std::vector<base::string16>& labels);
// Try to label password fields and upload |form|. This differs from
// OnFormSubmitted() in a few ways.
// - This function will only label the first <input type="password"> field
// as |password_type|. Other fields will stay unlabeled, as they
// should have been labeled during the upload for OnFormSubmitted().
// - If the |username_field| attribute is nonempty, we will additionally
// label the field with that name as the username field.
// - This function does not assume that |form| is being uploaded during
// the same browsing session as it was originally submitted (as we may
// not have the necessary information to classify the form at that time)
// so it bypasses the cache and doesn't log the same quality UMA metrics.
// |login_form_signature| may be empty. It is non-empty when the user fills
// and submits a login form using a generated password. In this case,
// |login_form_signature| should be set to the submitted form's signature.
// Note that in this case, |form.FormSignature()| gives the signature for the
// registration form on which the password was generated, rather than the
// submitted form's signature.
virtual bool UploadPasswordForm(const FormData& form,
const base::string16& username_field,
const ServerFieldType& pasword_type,
const std::string& login_form_signature);
// Resets cache.
virtual void Reset();
// Returns the value of the AutofillEnabled pref.
virtual bool IsAutofillEnabled() const;
protected:
// Test code should prefer to use this constructor.
AutofillManager(AutofillDriver* driver,
AutofillClient* client,
PersonalDataManager* personal_data);
// Uploads the form data to the Autofill server.
virtual void UploadFormData(const FormStructure& submitted_form);
// Logs quality metrics for the |submitted_form| and uploads the form data
// to the crowdsourcing server, if appropriate.
virtual void UploadFormDataAsyncCallback(
const FormStructure* submitted_form,
const base::TimeTicks& load_time,
const base::TimeTicks& interaction_time,
const base::TimeTicks& submission_time);
// Maps suggestion backend ID to and from an integer identifying it. Two of
// these intermediate integers are packed by MakeFrontendID to make the IDs
// that this class generates for the UI and for IPC.
virtual int BackendIDToInt(const std::string& backend_id) const;
virtual std::string IntToBackendID(int int_id) const;
// Methods for packing and unpacking credit card and profile IDs for sending
// and receiving to and from the renderer process.
int MakeFrontendID(const std::string& cc_backend_id,
const std::string& profile_backend_id) const;
void SplitFrontendID(int frontend_id,
std::string* cc_backend_id,
std::string* profile_backend_id) const;
ScopedVector<FormStructure>* form_structures() { return &form_structures_; }
// Exposed for testing.
AutofillExternalDelegate* external_delegate() {
return external_delegate_;
}
private:
// AutofillDownloadManager::Observer:
void OnLoadedServerPredictions(const std::string& response_xml) override;
// CardUnmaskDelegate:
void OnUnmaskResponse(const UnmaskResponse& response) override;
void OnUnmaskPromptClosed() override;
// wallet::RealPanWalletClient::Delegate:
IdentityProvider* GetIdentityProvider() override;
void OnDidGetRealPan(AutofillClient::GetRealPanResult result,
const std::string& real_pan) override;
// Returns false if Autofill is disabled or if no Autofill data is available.
bool RefreshDataModels();
// Returns true if the unique_id refers to a credit card and false if
// it refers to a profile.
bool IsCreditCard(int unique_id);
// Gets the profile referred by |unique_id|. Returns true if the profile
// exists.
bool GetProfile(int unique_id, const AutofillProfile** profile);
// Gets the credit card referred by |unique_id|. Returns true if the credit
// card exists.
bool GetCreditCard(int unique_id, const CreditCard** credit_card);
// Determines whether a fill on |form| initiated from |field| will wind up
// filling a credit card number. This is useful to determine if we will need
// to unmask a card.
bool WillFillCreditCardNumber(const FormData& form,
const FormFieldData& field);
// Fills or previews the credit card form.
// Assumes the form and field are valid.
void FillOrPreviewCreditCardForm(
AutofillDriver::RendererFormDataAction action,
int query_id,
const FormData& form,
const FormFieldData& field,
const CreditCard& credit_card);
// Fills or previews the profile form.
// Assumes the form and field are valid.
void FillOrPreviewProfileForm(AutofillDriver::RendererFormDataAction action,
int query_id,
const FormData& form,
const FormFieldData& field,
const AutofillProfile& profile);
// Fills or previews |data_model| in the |form|.
void FillOrPreviewDataModelForm(AutofillDriver::RendererFormDataAction action,
int query_id,
const FormData& form,
const FormFieldData& field,
const AutofillDataModel& data_model,
bool is_credit_card);
// Creates a FormStructure using the FormData received from the renderer. Will
// return an empty scoped_ptr if the data should not be processed for upload
// or personal data.
scoped_ptr<FormStructure> ValidateSubmittedForm(const FormData& form);
// Fills |form_structure| cached element corresponding to |form|.
// Returns false if the cached element was not found.
bool FindCachedForm(const FormData& form,
FormStructure** form_structure) const WARN_UNUSED_RESULT;
// Fills |form_structure| and |autofill_field| with the cached elements
// corresponding to |form| and |field|. This might have the side-effect of
// updating the cache. Returns false if the |form| is not autofillable, or if
// it is not already present in the cache and the cache is full.
bool GetCachedFormAndField(const FormData& form,
const FormFieldData& field,
FormStructure** form_structure,
AutofillField** autofill_field) WARN_UNUSED_RESULT;
// Returns the field corresponding to |form| and |field| that can be
// autofilled. Returns NULL if the field cannot be autofilled.
AutofillField* GetAutofillField(const FormData& form,
const FormFieldData& field)
WARN_UNUSED_RESULT;
// Re-parses |live_form| and adds the result to |form_structures_|.
// |cached_form| should be a pointer to the existing version of the form, or
// NULL if no cached version exists. The updated form is then written into
// |updated_form|. Returns false if the cache could not be updated.
bool UpdateCachedForm(const FormData& live_form,
const FormStructure* cached_form,
FormStructure** updated_form) WARN_UNUSED_RESULT;
// Returns a list of values from the stored profiles that match |type| and the
// value of |field| and returns the labels of the matching profiles. |labels|
// is filled with the Profile label.
std::vector<Suggestion> GetProfileSuggestions(
const FormStructure& form,
const FormFieldData& field,
const AutofillField& autofill_field) const;
// Returns a list of values from the stored credit cards that match |type| and
// the value of |field| and returns the labels of the matching credit cards.
std::vector<Suggestion> GetCreditCardSuggestions(
const FormFieldData& field,
const AutofillType& type) const;
// Parses the forms using heuristic matching and querying the Autofill server.
void ParseForms(const std::vector<FormData>& forms);
// Imports the form data, submitted by the user, into |personal_data_|.
void ImportFormData(const FormStructure& submitted_form);
// If |initial_interaction_timestamp_| is unset or is set to a later time than
// |interaction_timestamp|, updates the cached timestamp. The latter check is
// needed because IPC messages can arrive out of order.
void UpdateInitialInteractionTimestamp(
const base::TimeTicks& interaction_timestamp);
// Shared code to determine if |form| should be uploaded.
bool ShouldUploadForm(const FormStructure& form);
#ifdef ENABLE_FORM_DEBUG_DUMP
// Dumps the cached forms to a file on disk.
void DumpAutofillData(bool imported_cc) const;
#endif
// Provides driver-level context to the shared code of the component. Must
// outlive this object.
AutofillDriver* driver_;
AutofillClient* const client_;
// Handles real PAN requests.
wallet::RealPanWalletClient real_pan_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_;
std::list<std::string> autofilled_form_signatures_;
// Handles queries and uploads to Autofill servers. Will be NULL if
// the download manager functionality is disabled.
scoped_ptr<AutofillDownloadManager> download_manager_;
// Handles single-field autocomplete form data.
scoped_ptr<AutocompleteHistoryManager> autocomplete_history_manager_;
// Utilities for logging form events.
scoped_ptr<AutofillMetrics::FormEventLogger> address_form_event_logger_;
scoped_ptr<AutofillMetrics::FormEventLogger> credit_card_form_event_logger_;
// Have we logged whether Autofill is enabled for this page load?
bool has_logged_autofill_enabled_;
// Have we logged an address suggestions count metric for this page?
bool has_logged_address_suggestions_count_;
// Have we shown Autofill suggestions at least once?
bool did_show_suggestions_;
// Has the user manually edited at least one form field among the autofillable
// ones?
bool user_did_type_;
// Has the user autofilled a form on this page?
bool user_did_autofill_;
// Has the user edited a field that was previously autofilled?
bool user_did_edit_autofilled_field_;
// When the form finished loading.
std::map<FormData, base::TimeTicks> forms_loaded_timestamps_;
// When the user first interacted with a potentially fillable form on this
// page.
base::TimeTicks initial_interaction_timestamp_;
// Our copy of the form data.
ScopedVector<FormStructure> form_structures_;
// A copy of the credit card that's currently being unmasked, and data about
// the form.
CreditCard unmasking_card_;
// A copy of the latest card unmasking response.
UnmaskResponse unmask_response_;
int unmasking_query_id_;
FormData unmasking_form_;
FormFieldData unmasking_field_;
// Time when we requested the last real pan
base::Time real_pan_request_timestamp_;
// Masked copies of recently unmasked cards, to help avoid double-asking to
// save the card (in the prompt and in the infobar after submit).
std::vector<CreditCard> recently_unmasked_cards_;
#ifdef ENABLE_FORM_DEBUG_DUMP
// The last few autofilled forms (key/value pairs) submitted, for debugging.
// TODO(brettw) this should be removed. See DumpAutofillData.
std::vector<std::map<std::string, base::string16>>
recently_autofilled_forms_;
#endif
// Suggestion backend ID to ID mapping. We keep two maps to convert back and
// forth. These should be used only by BackendIDToInt and IntToBackendID.
// Note that the integers are not frontend IDs.
mutable std::map<std::string, int> backend_to_int_map_;
mutable std::map<int, std::string> int_to_backend_map_;
// Delegate to perform external processing (display, selection) on
// our behalf. Weak.
AutofillExternalDelegate* external_delegate_;
// Delegate used in test to get notifications on certain events.
AutofillManagerTestDelegate* test_delegate_;
base::WeakPtrFactory<AutofillManager> weak_ptr_factory_;
friend class AutofillManagerTest;
friend class FormStructureBrowserTest;
friend class FormStructureBrowserTestIos<ChromeUIWebViewWebTest>;
friend class FormStructureBrowserTestIos<ChromeWKWebViewWebTest>;
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
DeterminePossibleFieldTypesForUpload);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
DeterminePossibleFieldTypesForUploadStressTest);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
DisabledAutofillDispatchesError);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AddressFilledFormEvents);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AddressSubmittedFormEvents);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AddressWillSubmitFormEvents);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AddressSuggestionsCount);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AutofillIsEnabledAtPageLoad);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, CreditCardSelectedFormEvents);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, CreditCardFilledFormEvents);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, CreditCardGetRealPanDuration);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, CreditCardWillSubmitFormEvents);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, CreditCardSubmittedFormEvents);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, DeveloperEngagement);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, FormFillDuration);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest,
NoQualityMetricsForNonAutofillableForms);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, QualityMetrics);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, QualityMetricsForFailure);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, QualityMetricsWithExperimentId);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, SaneMetricsWithCacheMismatch);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, TestExternalDelegate);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
TestTabContentsWithExternalDelegate);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest,
UserHappinessFormLoadAndSubmission);
FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, UserHappinessFormInteraction);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
FormSubmittedAutocompleteEnabled);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
AutocompleteOffRespectedForAutocomplete);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest,
DontSaveCvcInAutocompleteHistory);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, DontOfferToSaveWalletCard);
FRIEND_TEST_ALL_PREFIXES(AutofillManagerTest, FillInUpdatedExpirationDate);
DISALLOW_COPY_AND_ASSIGN(AutofillManager);
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_MANAGER_H_