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

Side by Side 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: fixed test 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 unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/autofill/core/browser/autofill_manager.h" 5 #include "components/autofill/core/browser/autofill_manager.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <limits> 10 #include <limits>
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 autofill_field->Type().GetStorableType() != CREDIT_CARD_NUMBER) { 219 autofill_field->Type().GetStorableType() != CREDIT_CARD_NUMBER) {
220 return false; 220 return false;
221 } 221 }
222 222
223 static const int kShowScanCreditCardMaxValueLength = 6; 223 static const int kShowScanCreditCardMaxValueLength = 6;
224 return field.value.size() <= kShowScanCreditCardMaxValueLength && 224 return field.value.size() <= kShowScanCreditCardMaxValueLength &&
225 base::ContainsOnlyChars(CreditCard::StripSeparators(field.value), 225 base::ContainsOnlyChars(CreditCard::StripSeparators(field.value),
226 base::ASCIIToUTF16("0123456789")); 226 base::ASCIIToUTF16("0123456789"));
227 } 227 }
228 228
229 void AutofillManager::OnFormsSeen(const std::vector<FormData>& forms,
230 const TimeTicks& timestamp) {
231 if (!IsValidFormDataVector(forms))
232 return;
233
234 if (!driver_->RendererIsAvailable())
235 return;
236
237 bool enabled = IsAutofillEnabled();
238 if (!has_logged_autofill_enabled_) {
239 AutofillMetrics::LogIsAutofillEnabledAtPageLoad(enabled);
240 has_logged_autofill_enabled_ = true;
241 }
242
243 if (!enabled)
244 return;
245
246 for (const FormData& form : forms) {
247 forms_loaded_timestamps_[form] = timestamp;
248 }
249
250 ParseForms(forms);
251 }
252
229 bool AutofillManager::OnWillSubmitForm(const FormData& form, 253 bool AutofillManager::OnWillSubmitForm(const FormData& form,
230 const TimeTicks& timestamp) { 254 const TimeTicks& timestamp) {
231 if (!IsValidFormData(form)) 255 if (!IsValidFormData(form))
232 return false; 256 return false;
233 257
234 // We will always give Autocomplete a chance to save the data. 258 // We will always give Autocomplete a chance to save the data.
235 scoped_ptr<FormStructure> submitted_form = ValidateSubmittedForm(form); 259 scoped_ptr<FormStructure> submitted_form = ValidateSubmittedForm(form);
236 if (!submitted_form) { 260 if (!submitted_form) {
237 autocomplete_history_manager_->OnWillSubmitForm(form); 261 autocomplete_history_manager_->OnWillSubmitForm(form);
238 return false; 262 return false;
239 } 263 }
240 264
241 // However, if Autofill has recognized a field as CVC, that shouldn't be 265 // However, if Autofill has recognized a field as CVC, that shouldn't be
242 // saved. 266 // saved.
243 FormData form_for_autocomplete = submitted_form->ToFormData(); 267 FormData form_for_autocomplete = submitted_form->ToFormData();
244 for (size_t i = 0; i < submitted_form->field_count(); ++i) { 268 for (size_t i = 0; i < submitted_form->field_count(); ++i) {
245 if (submitted_form->field(i)->Type().GetStorableType() == 269 if (submitted_form->field(i)->Type().GetStorableType() ==
246 CREDIT_CARD_VERIFICATION_CODE) { 270 CREDIT_CARD_VERIFICATION_CODE) {
247 form_for_autocomplete.fields[i].should_autocomplete = false; 271 form_for_autocomplete.fields[i].should_autocomplete = false;
248 } 272 }
249 } 273 }
250 autocomplete_history_manager_->OnWillSubmitForm(form_for_autocomplete); 274 autocomplete_history_manager_->OnWillSubmitForm(form_for_autocomplete);
251 275
252 address_form_event_logger_->OnWillSubmitForm(); 276 address_form_event_logger_->OnWillSubmitForm();
253 credit_card_form_event_logger_->OnWillSubmitForm(); 277 credit_card_form_event_logger_->OnWillSubmitForm();
254 278
279 StartUploadProcess(std::move(submitted_form), timestamp, true);
280
281 return true;
282 }
283
284 bool AutofillManager::OnFormSubmitted(const FormData& form) {
285 if (!IsValidFormData(form))
286 return false;
287
288 // We will always give Autocomplete a chance to save the data.
289 scoped_ptr<FormStructure> submitted_form = ValidateSubmittedForm(form);
290 if (!submitted_form) {
291 return false;
292 }
293
294 address_form_event_logger_->OnFormSubmitted();
295 credit_card_form_event_logger_->OnFormSubmitted();
296
297 // Update Personal Data with the form's submitted data.
298 if (submitted_form->IsAutofillable())
299 ImportFormData(*submitted_form);
300
301 recently_unmasked_cards_.clear();
302
303 return true;
304 }
305
306 void AutofillManager::StartUploadProcess(
307 scoped_ptr<FormStructure> form_structure,
308 const TimeTicks& timestamp,
309 bool observed_submission) {
255 // Only upload server statistics and UMA metrics if at least some local data 310 // Only upload server statistics and UMA metrics if at least some local data
256 // is available to use as a baseline. 311 // is available to use as a baseline.
257 const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles(); 312 const std::vector<AutofillProfile*>& profiles = personal_data_->GetProfiles();
258 if (submitted_form->IsAutofillable()) { 313 if (observed_submission && form_structure->IsAutofillable()) {
314 // TODO(mathp): provide metrics for non-submission uploads.
259 AutofillMetrics::LogNumberOfProfilesAtAutofillableFormSubmission( 315 AutofillMetrics::LogNumberOfProfilesAtAutofillableFormSubmission(
260 personal_data_->GetProfiles().size()); 316 personal_data_->GetProfiles().size());
261 } 317 }
262 const std::vector<CreditCard*>& credit_cards = 318 const std::vector<CreditCard*>& credit_cards =
263 personal_data_->GetCreditCards(); 319 personal_data_->GetCreditCards();
264 if (!profiles.empty() || !credit_cards.empty()) { 320 if (!profiles.empty() || !credit_cards.empty()) {
265 // Copy the profile and credit card data, so that it can be accessed on a 321 // Copy the profile and credit card data, so that it can be accessed on a
266 // separate thread. 322 // separate thread.
267 std::vector<AutofillProfile> copied_profiles; 323 std::vector<AutofillProfile> copied_profiles;
268 copied_profiles.reserve(profiles.size()); 324 copied_profiles.reserve(profiles.size());
269 for (const AutofillProfile* profile : profiles) 325 for (const AutofillProfile* profile : profiles)
270 copied_profiles.push_back(*profile); 326 copied_profiles.push_back(*profile);
271 327
272 std::vector<CreditCard> copied_credit_cards; 328 std::vector<CreditCard> copied_credit_cards;
273 copied_credit_cards.reserve(credit_cards.size()); 329 copied_credit_cards.reserve(credit_cards.size());
274 for (const CreditCard* card : credit_cards) 330 for (const CreditCard* card : credit_cards)
275 copied_credit_cards.push_back(*card); 331 copied_credit_cards.push_back(*card);
276 332
277 // Note that ownership of |submitted_form| is passed to the second task, 333 // Note that ownership of |form_structure| is passed to the second task,
278 // using |base::Owned|. 334 // using |base::Owned|.
279 FormStructure* raw_submitted_form = submitted_form.get(); 335 FormStructure* raw_form = form_structure.get();
336 TimeTicks loaded_timestamp =
337 forms_loaded_timestamps_[raw_form->ToFormData()];
280 driver_->GetBlockingPool()->PostTaskAndReply( 338 driver_->GetBlockingPool()->PostTaskAndReply(
281 FROM_HERE, 339 FROM_HERE,
282 base::Bind(&DeterminePossibleFieldTypesForUpload, 340 base::Bind(&DeterminePossibleFieldTypesForUpload, copied_profiles,
283 copied_profiles, 341 copied_credit_cards, app_locale_, raw_form),
284 copied_credit_cards,
285 app_locale_,
286 raw_submitted_form),
287 base::Bind(&AutofillManager::UploadFormDataAsyncCallback, 342 base::Bind(&AutofillManager::UploadFormDataAsyncCallback,
288 weak_ptr_factory_.GetWeakPtr(), 343 weak_ptr_factory_.GetWeakPtr(),
289 base::Owned(submitted_form.release()), 344 base::Owned(form_structure.release()), loaded_timestamp,
290 forms_loaded_timestamps_[form], 345 initial_interaction_timestamp_, timestamp,
291 initial_interaction_timestamp_, 346 observed_submission));
292 timestamp));
293 } 347 }
294
295 return true;
296 } 348 }
297 349
298 bool AutofillManager::OnFormSubmitted(const FormData& form) { 350 void AutofillManager::UpdatePendingForm(const FormData& form) {
299 if (!IsValidFormData(form)) 351 // Process the current pending form if different than supplied |form|.
300 return false; 352 if (pending_form_data_ && !pending_form_data_->SameFormAs(form)) {
301 353 ProcessPendingFormForUpload();
302 // We will always give Autocomplete a chance to save the data.
303 scoped_ptr<FormStructure> submitted_form = ValidateSubmittedForm(form);
304 if (!submitted_form) {
305 return false;
306 } 354 }
307 355 // A new pending form is assigned.
308 address_form_event_logger_->OnFormSubmitted(); 356 pending_form_data_.reset(new FormData(form));
309 credit_card_form_event_logger_->OnFormSubmitted();
310
311 // Update Personal Data with the form's submitted data.
312 if (submitted_form->IsAutofillable())
313 ImportFormData(*submitted_form);
314
315 recently_unmasked_cards_.clear();
316
317 return true;
318 } 357 }
319 358
320 void AutofillManager::OnFormsSeen(const std::vector<FormData>& forms, 359 void AutofillManager::ProcessPendingFormForUpload() {
321 const TimeTicks& timestamp) { 360 if (!pending_form_data_)
322 if (!IsValidFormDataVector(forms))
323 return; 361 return;
324 362
325 if (!driver_->RendererIsAvailable()) 363 // We copy |pending_form_data_| to a new FormStructure to be consumed by the
326 return; 364 // upload process and reset |pending_form_data_|.
365 scoped_ptr<FormStructure> upload_form(new FormStructure(*pending_form_data_));
366 pending_form_data_.reset();
327 367
328 bool enabled = IsAutofillEnabled(); 368 StartUploadProcess(std::move(upload_form), base::TimeTicks::Now(), false);
329 if (!has_logged_autofill_enabled_) {
330 AutofillMetrics::LogIsAutofillEnabledAtPageLoad(enabled);
331 has_logged_autofill_enabled_ = true;
332 }
333
334 if (!enabled)
335 return;
336
337 for (size_t i = 0; i < forms.size(); ++i) {
338 forms_loaded_timestamps_[forms[i]] = timestamp;
339 }
340
341 ParseForms(forms);
342 } 369 }
343 370
344 void AutofillManager::OnTextFieldDidChange(const FormData& form, 371 void AutofillManager::OnTextFieldDidChange(const FormData& form,
345 const FormFieldData& field, 372 const FormFieldData& field,
346 const TimeTicks& timestamp) { 373 const TimeTicks& timestamp) {
347 if (!IsValidFormData(form) || !IsValidFormFieldData(field)) 374 if (!IsValidFormData(form) || !IsValidFormFieldData(field))
348 return; 375 return;
349 376
350 FormStructure* form_structure = NULL; 377 FormStructure* form_structure = NULL;
351 AutofillField* autofill_field = NULL; 378 AutofillField* autofill_field = NULL;
352 if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field)) 379 if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field))
353 return; 380 return;
354 381
382 UpdatePendingForm(form);
383
355 if (!user_did_type_) { 384 if (!user_did_type_) {
356 user_did_type_ = true; 385 user_did_type_ = true;
357 AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_TYPE); 386 AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_TYPE);
358 } 387 }
359 388
360 if (autofill_field->is_autofilled) { 389 if (autofill_field->is_autofilled) {
361 autofill_field->is_autofilled = false; 390 autofill_field->is_autofilled = false;
362 autofill_field->set_previously_autofilled(true); 391 autofill_field->set_previously_autofilled(true);
363 AutofillMetrics::LogUserHappinessMetric( 392 AutofillMetrics::LogUserHappinessMetric(
364 AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD); 393 AutofillMetrics::USER_DID_EDIT_AUTOFILLED_FIELD);
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 const CreditCard& credit_card) { 606 const CreditCard& credit_card) {
578 if (!IsValidFormData(form) || !IsValidFormFieldData(field) || 607 if (!IsValidFormData(form) || !IsValidFormFieldData(field) ||
579 !driver_->RendererIsAvailable()) { 608 !driver_->RendererIsAvailable()) {
580 return; 609 return;
581 } 610 }
582 611
583 FillOrPreviewDataModelForm(AutofillDriver::FORM_DATA_ACTION_FILL, query_id, 612 FillOrPreviewDataModelForm(AutofillDriver::FORM_DATA_ACTION_FILL, query_id,
584 form, field, credit_card, true); 613 form, field, credit_card, true);
585 } 614 }
586 615
616 void AutofillManager::OnFocusNoLongerOnForm() {
617 ProcessPendingFormForUpload();
618 }
619
587 void AutofillManager::OnDidPreviewAutofillFormData() { 620 void AutofillManager::OnDidPreviewAutofillFormData() {
588 if (test_delegate_) 621 if (test_delegate_)
589 test_delegate_->DidPreviewFormData(); 622 test_delegate_->DidPreviewFormData();
590 } 623 }
591 624
592 void AutofillManager::OnDidFillAutofillFormData(const TimeTicks& timestamp) { 625 void AutofillManager::OnDidFillAutofillFormData(const FormData& form,
626 const TimeTicks& timestamp) {
593 if (test_delegate_) 627 if (test_delegate_)
594 test_delegate_->DidFillFormData(); 628 test_delegate_->DidFillFormData();
595 629
630 UpdatePendingForm(form);
631
596 AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL); 632 AutofillMetrics::LogUserHappinessMetric(AutofillMetrics::USER_DID_AUTOFILL);
597 if (!user_did_autofill_) { 633 if (!user_did_autofill_) {
598 user_did_autofill_ = true; 634 user_did_autofill_ = true;
599 AutofillMetrics::LogUserHappinessMetric( 635 AutofillMetrics::LogUserHappinessMetric(
600 AutofillMetrics::USER_DID_AUTOFILL_ONCE); 636 AutofillMetrics::USER_DID_AUTOFILL_ONCE);
601 } 637 }
602 638
603 UpdateInitialInteractionTimestamp(timestamp); 639 UpdateInitialInteractionTimestamp(timestamp);
604 } 640 }
605 641
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
997 } 1033 }
998 1034
999 // Note that |submitted_form| is passed as a pointer rather than as a reference 1035 // Note that |submitted_form| is passed as a pointer rather than as a reference
1000 // so that we can get memory management right across threads. Note also that we 1036 // so that we can get memory management right across threads. Note also that we
1001 // explicitly pass in all the time stamps of interest, as the cached ones might 1037 // explicitly pass in all the time stamps of interest, as the cached ones might
1002 // get reset before this method executes. 1038 // get reset before this method executes.
1003 void AutofillManager::UploadFormDataAsyncCallback( 1039 void AutofillManager::UploadFormDataAsyncCallback(
1004 const FormStructure* submitted_form, 1040 const FormStructure* submitted_form,
1005 const TimeTicks& load_time, 1041 const TimeTicks& load_time,
1006 const TimeTicks& interaction_time, 1042 const TimeTicks& interaction_time,
1007 const TimeTicks& submission_time) { 1043 const TimeTicks& submission_time,
1008 submitted_form->LogQualityMetrics( 1044 bool observed_submission) {
1009 load_time, interaction_time, submission_time, client_->GetRapporService(), 1045 // TODO(mathp): Have different set of metrics for non-submission uploads.
1010 did_show_suggestions_); 1046 if (observed_submission) {
1047 submitted_form->LogQualityMetrics(
1048 load_time, interaction_time, submission_time,
1049 client_->GetRapporService(), did_show_suggestions_);
1050 }
1011 1051
1052 // TODO(crbug.com/555015): Differentiate non-submission uploads in the
1053 // uploaded payload.
1012 if (submitted_form->ShouldBeCrowdsourced()) 1054 if (submitted_form->ShouldBeCrowdsourced())
1013 UploadFormData(*submitted_form); 1055 UploadFormData(*submitted_form);
1014 } 1056 }
1015 1057
1016 void AutofillManager::UploadFormData(const FormStructure& submitted_form) { 1058 void AutofillManager::UploadFormData(const FormStructure& submitted_form) {
1017 if (!download_manager_) 1059 if (!download_manager_)
1018 return; 1060 return;
1019 1061
1020 // Check if the form is among the forms that were recently auto-filled. 1062 // Check if the form is among the forms that were recently auto-filled.
1021 bool was_autofilled = false; 1063 bool was_autofilled = false;
(...skipping 20 matching lines...) Expand all
1042 address_form_event_logger_.reset( 1084 address_form_event_logger_.reset(
1043 new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */)); 1085 new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */));
1044 credit_card_form_event_logger_.reset( 1086 credit_card_form_event_logger_.reset(
1045 new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */)); 1087 new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */));
1046 has_logged_autofill_enabled_ = false; 1088 has_logged_autofill_enabled_ = false;
1047 has_logged_address_suggestions_count_ = false; 1089 has_logged_address_suggestions_count_ = false;
1048 did_show_suggestions_ = false; 1090 did_show_suggestions_ = false;
1049 user_did_type_ = false; 1091 user_did_type_ = false;
1050 user_did_autofill_ = false; 1092 user_did_autofill_ = false;
1051 user_did_edit_autofilled_field_ = false; 1093 user_did_edit_autofilled_field_ = false;
1094 ProcessPendingFormForUpload();
1095 DCHECK(!pending_form_data_);
1052 unmask_request_ = payments::PaymentsClient::UnmaskRequestDetails(); 1096 unmask_request_ = payments::PaymentsClient::UnmaskRequestDetails();
1053 unmasking_query_id_ = -1; 1097 unmasking_query_id_ = -1;
1054 unmasking_form_ = FormData(); 1098 unmasking_form_ = FormData();
1055 unmasking_field_ = FormFieldData(); 1099 unmasking_field_ = FormFieldData();
1056 forms_loaded_timestamps_.clear(); 1100 forms_loaded_timestamps_.clear();
1057 initial_interaction_timestamp_ = TimeTicks(); 1101 initial_interaction_timestamp_ = TimeTicks();
1058 external_delegate_->Reset(); 1102 external_delegate_->Reset();
1059 } 1103 }
1060 1104
1061 AutofillManager::AutofillManager(AutofillDriver* driver, 1105 AutofillManager::AutofillManager(AutofillDriver* driver,
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 1528
1485 void AutofillManager::ParseForms(const std::vector<FormData>& forms) { 1529 void AutofillManager::ParseForms(const std::vector<FormData>& forms) {
1486 if (forms.empty()) 1530 if (forms.empty())
1487 return; 1531 return;
1488 1532
1489 std::vector<FormStructure*> non_queryable_forms; 1533 std::vector<FormStructure*> non_queryable_forms;
1490 std::vector<FormStructure*> queryable_forms; 1534 std::vector<FormStructure*> queryable_forms;
1491 for (const FormData& form : forms) { 1535 for (const FormData& form : forms) {
1492 scoped_ptr<FormStructure> form_structure(new FormStructure(form)); 1536 scoped_ptr<FormStructure> form_structure(new FormStructure(form));
1493 form_structure->ParseFieldTypesFromAutocompleteAttributes(); 1537 form_structure->ParseFieldTypesFromAutocompleteAttributes();
1494
1495 if (!form_structure->ShouldBeParsed()) 1538 if (!form_structure->ShouldBeParsed())
1496 continue; 1539 continue;
1497 1540
1498 form_structure->DetermineHeuristicTypes(); 1541 form_structure->DetermineHeuristicTypes();
1499 1542
1500 // Ownership is transferred to |form_structures_| which maintains it until 1543 // Ownership is transferred to |form_structures_| which maintains it until
1501 // the manager is Reset() or destroyed. It is safe to use references below 1544 // the manager is Reset() or destroyed. It is safe to use references below
1502 // as long as receivers don't take ownership. 1545 // as long as receivers don't take ownership.
1503 form_structures_.push_back(form_structure.Pass()); 1546 form_structures_.push_back(form_structure.Pass());
1504 1547
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1631 if (i > 0) 1674 if (i > 0)
1632 fputs("Next oldest form:\n", file); 1675 fputs("Next oldest form:\n", file);
1633 } 1676 }
1634 fputs("\n", file); 1677 fputs("\n", file);
1635 1678
1636 fclose(file); 1679 fclose(file);
1637 } 1680 }
1638 #endif // ENABLE_FORM_DEBUG_DUMP 1681 #endif // ENABLE_FORM_DEBUG_DUMP
1639 1682
1640 } // namespace autofill 1683 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/autofill_manager.h ('k') | components/autofill/core/browser/autofill_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698