Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(452)

Unified Diff: chrome/browser/autofill/autofill_manager.cc

Issue 7747009: Add metrics to track Autofill "user happiness" (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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());
}

Powered by Google App Engine
This is Rietveld 408576698