| Index: chrome/browser/autofill/autofill_manager.cc
|
| diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
|
| index 390c8d14cfa324eb590d84ec85543d51d9de2c0a..238b92175f1c8fa11daeddc5dfe728809a6f82a6 100644
|
| --- a/chrome/browser/autofill/autofill_manager.cc
|
| +++ b/chrome/browser/autofill/autofill_manager.cc
|
| @@ -227,7 +227,11 @@ AutofillManager::AutofillManager(TabContentsWrapper* tab_contents)
|
| disable_download_manager_requests_(false),
|
| metric_logger_(new AutofillMetrics),
|
| has_logged_autofill_enabled_(false),
|
| - has_logged_address_suggestions_count_(false) {
|
| + has_logged_address_suggestions_count_(false),
|
| + did_show_suggestions_(false),
|
| + user_did_type_(false),
|
| + user_did_autofill_(false),
|
| + user_did_edit_autofilled_field_(false) {
|
| DCHECK(tab_contents);
|
|
|
| // |personal_data_| is NULL when using TestTabContents.
|
| @@ -278,12 +282,16 @@ bool AutofillManager::OnMessageReceived(const IPC::Message& message) {
|
| IPC_BEGIN_MESSAGE_MAP(AutofillManager, message)
|
| IPC_MESSAGE_HANDLER(AutofillHostMsg_FormsSeen, OnFormsSeen)
|
| IPC_MESSAGE_HANDLER(AutofillHostMsg_FormSubmitted, OnFormSubmitted)
|
| + IPC_MESSAGE_HANDLER(AutofillHostMsg_TextFieldDidChange,
|
| + OnTextFieldDidChange)
|
| IPC_MESSAGE_HANDLER(AutofillHostMsg_QueryFormFieldAutofill,
|
| OnQueryFormFieldAutofill)
|
| IPC_MESSAGE_HANDLER(AutofillHostMsg_ShowAutofillDialog,
|
| OnShowAutofillDialog)
|
| IPC_MESSAGE_HANDLER(AutofillHostMsg_FillAutofillFormData,
|
| OnFillAutofillFormData)
|
| + IPC_MESSAGE_HANDLER(AutofillHostMsg_DidPreviewAutofillFormData,
|
| + OnDidPreviewAutofillFormData)
|
| IPC_MESSAGE_HANDLER(AutofillHostMsg_DidFillAutofillFormData,
|
| OnDidFillAutofillFormData)
|
| IPC_MESSAGE_HANDLER(AutofillHostMsg_DidShowAutofillSuggestions,
|
| @@ -298,9 +306,6 @@ void AutofillManager::OnFormSubmitted(const FormData& form) {
|
| // Let AutoComplete know as well.
|
| tab_contents_wrapper_->autocomplete_history_manager()->OnFormSubmitted(form);
|
|
|
| - if (!IsAutofillEnabled())
|
| - return;
|
| -
|
| if (tab_contents()->browser_context()->IsOffTheRecord())
|
| return;
|
|
|
| @@ -315,6 +320,14 @@ void AutofillManager::OnFormSubmitted(const FormData& form) {
|
| if (!submitted_form.ShouldBeParsed(true))
|
| return;
|
|
|
| + if (user_did_autofill_) {
|
| + metric_logger_->LogUserHappinessMetric(
|
| + AutofillMetrics::FORM_SUBMITTED_AFTER_AUTOFILL);
|
| + } else {
|
| + metric_logger_->LogUserHappinessMetric(
|
| + AutofillMetrics::FORM_SUBMITTED_WITHOUT_AUTOFILL);
|
| + }
|
| +
|
| // Ignore forms not present in our cache. These are typically forms with
|
| // wonky JavaScript that also makes them not auto-fillable.
|
| FormStructure* cached_submitted_form;
|
| @@ -322,6 +335,10 @@ void AutofillManager::OnFormSubmitted(const FormData& form) {
|
| return;
|
| submitted_form.UpdateFromCache(*cached_submitted_form);
|
|
|
| + // We delay this check until now for the sake of metrics.
|
| + if (!IsAutofillEnabled())
|
| + return;
|
| +
|
| // Only upload server statistics and UMA metrics if at least some local data
|
| // is available to use as a baseline.
|
| if (!personal_data_->profiles().empty() ||
|
| @@ -352,6 +369,28 @@ void AutofillManager::OnFormsSeen(const std::vector<FormData>& forms) {
|
| ParseForms(forms);
|
| }
|
|
|
| +void AutofillManager::OnTextFieldDidChange(const FormData& form,
|
| + const FormField& field) {
|
| + if (user_did_type_ && user_did_edit_autofilled_field_)
|
| + return;
|
| +
|
| + FormStructure* form_structure = NULL;
|
| + AutofillField* autofill_field = NULL;
|
| + if (!FindCachedFormAndField(form, field, &form_structure, &autofill_field))
|
| + return;
|
| +
|
| + if (!user_did_type_) {
|
| + user_did_type_ = true;
|
| + metric_logger_->LogUserHappinessMetric(AutofillMetrics::USER_DID_TYPE);
|
| + }
|
| +
|
| + if (!user_did_edit_autofilled_field_ && autofill_field->is_autofilled) {
|
| + user_did_edit_autofilled_field_ = true;
|
| + metric_logger_->LogUserHappinessMetric(
|
| + AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD);
|
| + }
|
| +}
|
| +
|
| void AutofillManager::OnQueryFormFieldAutofill(
|
| int query_id,
|
| const webkit_glue::FormData& form,
|
| @@ -507,6 +546,10 @@ void AutofillManager::OnFillAutofillFormData(int query_id,
|
| AutofillType(field_type).group());
|
| FillCreditCardFormField(credit_card, field_type, &(*iter));
|
| }
|
| +
|
| + // Mark the cached field as autofilled, so that we can detect when a
|
| + // user edits an autofilled field (for metrics).
|
| + autofill_field->is_autofilled = true;
|
| break;
|
| }
|
| }
|
| @@ -557,6 +600,10 @@ void AutofillManager::OnFillAutofillFormData(int query_id,
|
| DCHECK_EQ(AutofillType::CREDIT_CARD, field_group_type);
|
| FillCreditCardFormField(credit_card, field_type, &result.fields[j]);
|
| }
|
| +
|
| + // Mark the cached field as autofilled, so that we can detect when a user
|
| + // edits an autofilled field (for metrics).
|
| + form_structure->field(k)->is_autofilled = true;
|
| }
|
|
|
| // We found a matching field in the |form_structure|, so on the next
|
| @@ -581,18 +628,43 @@ void AutofillManager::OnShowAutofillDialog() {
|
| browser->ShowOptionsTab(chrome::kAutofillSubPage);
|
| }
|
|
|
| +void AutofillManager::OnDidPreviewAutofillFormData() {
|
| + NotificationService::current()->Notify(
|
| + chrome::NOTIFICATION_AUTOFILL_DID_FILL_FORM_DATA,
|
| + Source<RenderViewHost>(tab_contents()->render_view_host()),
|
| + NotificationService::NoDetails());
|
| +}
|
| +
|
| +
|
| void AutofillManager::OnDidFillAutofillFormData() {
|
| NotificationService::current()->Notify(
|
| chrome::NOTIFICATION_AUTOFILL_DID_FILL_FORM_DATA,
|
| Source<RenderViewHost>(tab_contents()->render_view_host()),
|
| NotificationService::NoDetails());
|
| +
|
| + metric_logger_->LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL);
|
| + if (!user_did_autofill_) {
|
| + user_did_autofill_ = true;
|
| + metric_logger_->LogUserHappinessMetric(
|
| + AutofillMetrics::USER_DID_AUTOFILL_FIRST_TIME);
|
| + }
|
| }
|
|
|
| -void AutofillManager::OnDidShowAutofillSuggestions() {
|
| +void AutofillManager::OnDidShowAutofillSuggestions(bool is_new_popup) {
|
| NotificationService::current()->Notify(
|
| chrome::NOTIFICATION_AUTOFILL_DID_SHOW_SUGGESTIONS,
|
| Source<RenderViewHost>(tab_contents()->render_view_host()),
|
| NotificationService::NoDetails());
|
| +
|
| + if (is_new_popup) {
|
| + metric_logger_->LogUserHappinessMetric(AutofillMetrics::SUGGESTIONS_SHOWN);
|
| +
|
| + if (!did_show_suggestions_) {
|
| + did_show_suggestions_ = true;
|
| + metric_logger_->LogUserHappinessMetric(
|
| + AutofillMetrics::SUGGESTIONS_SHOWN_FIRST_TIME);
|
| + }
|
| + }
|
| }
|
|
|
| void AutofillManager::OnLoadedServerPredictions(
|
| @@ -644,7 +716,7 @@ void AutofillManager::DeterminePossibleFieldTypesForUpload(
|
| // For each field in the |submitted_form|, extract the value. Then for each
|
| // profile or credit card, identify any stored types that match the value.
|
| for (size_t i = 0; i < submitted_form->field_count(); i++) {
|
| - const AutofillField* field = submitted_form->field(i);
|
| + AutofillField* field = submitted_form->field(i);
|
| string16 value = CollapseWhitespace(field->value, false);
|
| FieldTypeSet matching_types;
|
| for (std::vector<FormGroup*>::const_iterator it = stored_data.begin();
|
| @@ -655,7 +727,7 @@ void AutofillManager::DeterminePossibleFieldTypesForUpload(
|
| if (matching_types.empty())
|
| matching_types.insert(UNKNOWN_TYPE);
|
|
|
| - submitted_form->set_possible_types(i, matching_types);
|
| + field->set_possible_types(matching_types);
|
| }
|
| }
|
|
|
| @@ -702,6 +774,10 @@ void AutofillManager::Reset() {
|
| form_structures_.reset();
|
| has_logged_autofill_enabled_ = false;
|
| has_logged_address_suggestions_count_ = false;
|
| + did_show_suggestions_ = false;
|
| + user_did_type_ = false;
|
| + user_did_autofill_ = false;
|
| + user_did_edit_autofilled_field_ = false;
|
| }
|
|
|
| AutofillManager::AutofillManager(TabContentsWrapper* tab_contents,
|
| @@ -713,7 +789,11 @@ AutofillManager::AutofillManager(TabContentsWrapper* tab_contents,
|
| disable_download_manager_requests_(true),
|
| metric_logger_(new AutofillMetrics),
|
| has_logged_autofill_enabled_(false),
|
| - has_logged_address_suggestions_count_(false) {
|
| + has_logged_address_suggestions_count_(false),
|
| + did_show_suggestions_(false),
|
| + user_did_type_(false),
|
| + user_did_autofill_(false),
|
| + user_did_edit_autofilled_field_(false) {
|
| DCHECK(tab_contents);
|
| }
|
|
|
| @@ -1013,6 +1093,9 @@ void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
|
| form_structures_.push_back(*iter);
|
| }
|
|
|
| + if (!form_structures_.empty())
|
| + metric_logger_->LogUserHappinessMetric(AutofillMetrics::FORMS_LOADED);
|
| +
|
| CheckForPopularForms(form_structures_.get(), tab_contents_wrapper_,
|
| tab_contents());
|
| }
|
|
|