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()); |
} |