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

Unified Diff: components/autofill/core/browser/autofill_manager.cc

Issue 1494373003: [Autofill] Send Autofill upload when active form loses focus. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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: components/autofill/core/browser/autofill_manager.cc
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index e3c5e3c66c9fc84f24197da1106f06db992fd77a..605a780d3dca2b510d9c5b5e99bf1c0b92dcab3f 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -226,6 +226,30 @@ bool AutofillManager::ShouldShowScanCreditCard(const FormData& form,
base::ASCIIToUTF16("0123456789"));
}
+void AutofillManager::OnFormsSeen(const std::vector<FormData>& forms,
+ const TimeTicks& timestamp) {
+ if (!IsValidFormDataVector(forms))
+ return;
+
+ if (!driver_->RendererIsAvailable())
+ return;
+
+ bool enabled = IsAutofillEnabled();
+ if (!has_logged_autofill_enabled_) {
+ AutofillMetrics::LogIsAutofillEnabledAtPageLoad(enabled);
+ has_logged_autofill_enabled_ = true;
+ }
+
+ if (!enabled)
+ return;
+
+ for (size_t i = 0; i < forms.size(); ++i) {
vabr (Chromium) 2015/12/07 09:47:34 A range-based for-loop would be easier to read: fo
Mathieu 2015/12/07 14:23:08 Done.
+ forms_loaded_timestamps_[forms[i]] = timestamp;
+ }
+
+ ParseForms(forms);
+}
+
bool AutofillManager::OnWillSubmitForm(const FormData& form,
const TimeTicks& timestamp) {
if (!IsValidFormData(form))
@@ -252,10 +276,42 @@ bool AutofillManager::OnWillSubmitForm(const FormData& form,
address_form_event_logger_->OnWillSubmitForm();
credit_card_form_event_logger_->OnWillSubmitForm();
+ StartUploadProcess(submitted_form.Pass(), timestamp, true);
vabr (Chromium) 2015/12/07 09:47:34 nit: std::move(submitted_form) instead of .Pass()
Mathieu 2015/12/07 14:23:07 Done.
+
+ return true;
+}
+
+bool AutofillManager::OnFormSubmitted(const FormData& form) {
+ if (!IsValidFormData(form))
+ return false;
+
+ // We will always give Autocomplete a chance to save the data.
+ scoped_ptr<FormStructure> submitted_form = ValidateSubmittedForm(form);
+ if (!submitted_form) {
+ return false;
+ }
+
+ address_form_event_logger_->OnFormSubmitted();
+ credit_card_form_event_logger_->OnFormSubmitted();
+
+ // Update Personal Data with the form's submitted data.
+ if (submitted_form->IsAutofillable())
+ ImportFormData(*submitted_form);
+
+ recently_unmasked_cards_.clear();
+
+ return true;
+}
+
+void AutofillManager::StartUploadProcess(
+ scoped_ptr<FormStructure> form_structure,
+ const TimeTicks& timestamp,
+ bool observed_submission) {
// Only upload server statistics and UMA metrics if at least some local data
// is available to use as a baseline.
const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
- if (submitted_form->IsAutofillable()) {
+ if (observed_submission && form_structure->IsAutofillable()) {
+ // TODO(mathp): provide metrics for non-submission uploads.
AutofillMetrics::LogNumberOfProfilesAtAutofillableFormSubmission(
personal_data_->GetProfiles().size());
}
@@ -274,71 +330,42 @@ bool AutofillManager::OnWillSubmitForm(const FormData& form,
for (const CreditCard* card : credit_cards)
copied_credit_cards.push_back(*card);
- // Note that ownership of |submitted_form| is passed to the second task,
+ // Note that ownership of |form_structure| is passed to the second task,
// using |base::Owned|.
- FormStructure* raw_submitted_form = submitted_form.get();
+ FormStructure* raw_form = form_structure.get();
+ TimeTicks loaded_timestamp =
+ forms_loaded_timestamps_[raw_form->ToFormData()];
driver_->GetBlockingPool()->PostTaskAndReply(
FROM_HERE,
- base::Bind(&DeterminePossibleFieldTypesForUpload,
- copied_profiles,
- copied_credit_cards,
- app_locale_,
- raw_submitted_form),
+ base::Bind(&DeterminePossibleFieldTypesForUpload, copied_profiles,
+ copied_credit_cards, app_locale_, raw_form),
base::Bind(&AutofillManager::UploadFormDataAsyncCallback,
weak_ptr_factory_.GetWeakPtr(),
- base::Owned(submitted_form.release()),
- forms_loaded_timestamps_[form],
- initial_interaction_timestamp_,
- timestamp));
+ base::Owned(form_structure.release()), loaded_timestamp,
vabr (Chromium) 2015/12/07 09:47:33 Please use base::Passed(&form_structure) instead.
Mathieu 2015/12/07 14:23:08 I'm having difficulty with this change: Here is th
vabr (Chromium) 2015/12/07 15:32:50 Yes, sorry, I missed that the receiving method tak
+ initial_interaction_timestamp_, timestamp,
+ observed_submission));
}
-
- return true;
}
-bool AutofillManager::OnFormSubmitted(const FormData& form) {
- if (!IsValidFormData(form))
- return false;
-
- // We will always give Autocomplete a chance to save the data.
- scoped_ptr<FormStructure> submitted_form = ValidateSubmittedForm(form);
- if (!submitted_form) {
- return false;
+void AutofillManager::UpdatePendingForm(const FormData& form) {
+ // Process the current pending form if different than supplied |form|.
+ if (pending_form_data_ && !pending_form_data_->SameFormAs(form)) {
+ ProcessPendingFormForUpload();
}
-
- address_form_event_logger_->OnFormSubmitted();
- credit_card_form_event_logger_->OnFormSubmitted();
-
- // Update Personal Data with the form's submitted data.
- if (submitted_form->IsAutofillable())
- ImportFormData(*submitted_form);
-
- recently_unmasked_cards_.clear();
-
- return true;
+ // A new pending form is assigned.
+ pending_form_data_.reset(new FormData(form));
}
-void AutofillManager::OnFormsSeen(const std::vector<FormData>& forms,
- const TimeTicks& timestamp) {
- if (!IsValidFormDataVector(forms))
- return;
-
- if (!driver_->RendererIsAvailable())
- return;
-
- bool enabled = IsAutofillEnabled();
- if (!has_logged_autofill_enabled_) {
- AutofillMetrics::LogIsAutofillEnabledAtPageLoad(enabled);
- has_logged_autofill_enabled_ = true;
- }
-
- if (!enabled)
+void AutofillManager::ProcessPendingFormForUpload() {
+ if (!pending_form_data_)
return;
- for (size_t i = 0; i < forms.size(); ++i) {
- forms_loaded_timestamps_[forms[i]] = timestamp;
- }
+ // We copy |pending_form_data_| to a new FormStructure to be consumed by the
vabr (Chromium) 2015/12/07 09:47:33 Why not just pass |pending_form_data_| to StartUpl
Mathieu 2015/12/07 14:23:08 StartUploadProcess needs a FormStructure to do its
vabr (Chromium) 2015/12/07 15:32:50 My bad, I overlooked that one is FormData and the
+ // upload process and reset |pending_form_data_|.
+ scoped_ptr<FormStructure> upload_form(new FormStructure(*pending_form_data_));
+ pending_form_data_.reset();
- ParseForms(forms);
+ StartUploadProcess(upload_form.Pass(), base::TimeTicks::Now(), false);
vabr (Chromium) 2015/12/07 09:47:34 Pass -> std::move
Mathieu 2015/12/07 14:23:08 Done.
}
void AutofillManager::OnTextFieldDidChange(const FormData& form,
@@ -352,6 +379,8 @@ void AutofillManager::OnTextFieldDidChange(const FormData& form,
if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field))
return;
+ UpdatePendingForm(form);
+
if (!user_did_type_) {
user_did_type_ = true;
AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_TYPE);
@@ -584,15 +613,22 @@ void AutofillManager::FillCreditCardForm(int query_id,
form, field, credit_card, true);
}
+void AutofillManager::OnFocusNoLongerOnForm() {
+ ProcessPendingFormForUpload();
+}
+
void AutofillManager::OnDidPreviewAutofillFormData() {
if (test_delegate_)
test_delegate_->DidPreviewFormData();
}
-void AutofillManager::OnDidFillAutofillFormData(const TimeTicks& timestamp) {
+void AutofillManager::OnDidFillAutofillFormData(const FormData& form,
+ const TimeTicks& timestamp) {
if (test_delegate_)
test_delegate_->DidFillFormData();
+ UpdatePendingForm(form);
+
AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL);
if (!user_did_autofill_) {
user_did_autofill_ = true;
@@ -1004,11 +1040,16 @@ void AutofillManager::UploadFormDataAsyncCallback(
const FormStructure* submitted_form,
const TimeTicks& load_time,
const TimeTicks& interaction_time,
- const TimeTicks& submission_time) {
+ const TimeTicks& submission_time,
+ bool observed_submission) {
+ // TODO(mathp): Have different set of metrics for non-submission uploads.
+ if (observed_submission) {
submitted_form->LogQualityMetrics(
load_time, interaction_time, submission_time, client_->GetRapporService(),
did_show_suggestions_);
+ }
+ // TODO(mathp): Differentiate non-submission uploads in the uploaded payload.
vabr (Chromium) 2015/12/07 09:47:34 optional nit: Could you use TODO(crbug.com/xxxxxxx
Mathieu 2015/12/07 14:23:08 Done.
if (submitted_form->ShouldBeCrowdsourced())
UploadFormData(*submitted_form);
}
@@ -1049,6 +1090,10 @@ void AutofillManager::Reset() {
user_did_type_ = false;
user_did_autofill_ = false;
user_did_edit_autofilled_field_ = false;
+ if (pending_form_data_) {
vabr (Chromium) 2015/12/07 09:47:33 ProcessPendingFormForUpload seems to be currently
Mathieu 2015/12/07 14:23:08 You're right. It's tolerant to null pending_form_d
+ ProcessPendingFormForUpload();
+ }
+ pending_form_data_.reset();
vabr (Chromium) 2015/12/07 09:47:33 There seems to be no way that ProcessPendingFormFo
Mathieu 2015/12/07 14:23:08 Acknowledged.
unmask_request_ = payments::PaymentsClient::UnmaskRequestDetails();
unmasking_query_id_ = -1;
unmasking_form_ = FormData();
@@ -1491,7 +1536,6 @@ void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
for (const FormData& form : forms) {
scoped_ptr<FormStructure> form_structure(new FormStructure(form));
form_structure->ParseFieldTypesFromAutocompleteAttributes();
-
if (!form_structure->ShouldBeParsed())
continue;

Powered by Google App Engine
This is Rietveld 408576698