Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/autofill/autofill_manager.h" | 5 #include "chrome/browser/autofill/autofill_manager.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 199 return; | 199 return; |
| 200 | 200 |
| 201 if (tab_contents_->profile()->IsOffTheRecord()) | 201 if (tab_contents_->profile()->IsOffTheRecord()) |
| 202 return; | 202 return; |
| 203 | 203 |
| 204 // Don't save data that was submitted through JavaScript. | 204 // Don't save data that was submitted through JavaScript. |
| 205 if (!form.user_submitted) | 205 if (!form.user_submitted) |
| 206 return; | 206 return; |
| 207 | 207 |
| 208 // Grab a copy of the form data. | 208 // Grab a copy of the form data. |
| 209 upload_form_structure_.reset(new FormStructure(form)); | 209 FormStructure submitted_form(form); |
| 210 | 210 |
| 211 // Disregard forms that we wouldn't ever autofill in the first place. | 211 // Disregard forms that we wouldn't ever autofill in the first place. |
| 212 if (!upload_form_structure_->ShouldBeParsed(true)) | 212 if (!submitted_form.ShouldBeParsed(true)) |
| 213 return; | 213 return; |
| 214 | 214 |
| 215 FormStructure* cached_upload_form_structure = NULL; | 215 DeterminePossibleFieldTypesForUpload(&submitted_form); |
| 216 AutoFillField* ignored; | 216 LogMetricsAboutSubmittedForm(form, &submitted_form); |
| 217 if (!FindCachedFormAndField(form, form.fields.front(), | |
| 218 &cached_upload_form_structure, &ignored)) { | |
| 219 cached_upload_form_structure = NULL; | |
| 220 } | |
| 221 | 217 |
| 222 DeterminePossibleFieldTypesForUpload(cached_upload_form_structure); | 218 if (!submitted_form.IsAutoFillable(true)) |
| 223 // TODO(isherman): Consider uploading to server here rather than in | |
| 224 // HandleSubmit(). | |
|
Ilya Sherman
2011/01/18 23:02:36
Are you sure that we should only upload data to th
dhollowa
2011/01/18 23:26:15
Yes, typo. UploadFormData should be moved up abov
dhollowa
2011/01/19 17:00:44
Done.
| |
| 225 | |
| 226 if (!upload_form_structure_->IsAutoFillable(true)) | |
| 227 return; | 219 return; |
| 228 | 220 |
| 229 HandleSubmit(); | 221 ImportFormData(submitted_form); |
| 222 UploadFormData(submitted_form); | |
| 230 } | 223 } |
| 231 | 224 |
| 232 void AutoFillManager::OnFormsSeen(const std::vector<FormData>& forms) { | 225 void AutoFillManager::OnFormsSeen(const std::vector<FormData>& forms) { |
| 233 if (!IsAutoFillEnabled()) | 226 if (!IsAutoFillEnabled()) |
| 234 return; | 227 return; |
| 235 | 228 |
| 236 ParseForms(forms); | 229 ParseForms(forms); |
| 237 } | 230 } |
| 238 | 231 |
| 239 void AutoFillManager::OnQueryFormFieldAutoFill( | 232 void AutoFillManager::OnQueryFormFieldAutoFill( |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 478 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); | 471 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); |
| 479 prefs->ClearPref(prefs::kFormAutofillEnabled); | 472 prefs->ClearPref(prefs::kFormAutofillEnabled); |
| 480 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); | 473 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); |
| 481 return enabled; | 474 return enabled; |
| 482 } | 475 } |
| 483 | 476 |
| 484 return prefs->GetBoolean(prefs::kAutoFillEnabled); | 477 return prefs->GetBoolean(prefs::kAutoFillEnabled); |
| 485 } | 478 } |
| 486 | 479 |
| 487 void AutoFillManager::DeterminePossibleFieldTypesForUpload( | 480 void AutoFillManager::DeterminePossibleFieldTypesForUpload( |
| 488 const FormStructure* cached_upload_form_structure) { | 481 FormStructure* submitted_form) { |
| 489 for (size_t i = 0; i < upload_form_structure_->field_count(); i++) { | 482 for (size_t i = 0; i < submitted_form->field_count(); i++) { |
| 490 const AutoFillField* field = upload_form_structure_->field(i); | 483 const AutoFillField* field = submitted_form->field(i); |
| 491 FieldTypeSet field_types; | 484 FieldTypeSet field_types; |
| 492 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); | 485 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); |
| 493 DCHECK(!field_types.empty()); | 486 DCHECK(!field_types.empty()); |
| 494 upload_form_structure_->set_possible_types(i, field_types); | 487 submitted_form->set_possible_types(i, field_types); |
| 488 } | |
| 489 } | |
| 490 | |
| 491 void AutoFillManager::LogMetricsAboutSubmittedForm( | |
| 492 const FormData& form, | |
| 493 const FormStructure* submitted_form) { | |
| 494 FormStructure* cached_submitted_form = NULL; | |
| 495 AutoFillField* ignored; | |
| 496 if (!FindCachedFormAndField(form, form.fields.front(), | |
| 497 &cached_submitted_form, &ignored)) { | |
| 498 cached_submitted_form = NULL; | |
|
Ilya Sherman
2011/01/18 23:02:36
I wonder if we can make this a NOTREACHED()
dhollowa
2011/01/18 23:29:03
I would think yes, and that would be preferable.
| |
| 499 } | |
| 500 | |
| 501 for (size_t i = 0; i < submitted_form->field_count(); i++) { | |
| 502 const AutoFillField* field = submitted_form->field(i); | |
| 503 FieldTypeSet field_types; | |
| 504 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); | |
| 505 DCHECK(!field_types.empty()); | |
| 495 | 506 |
| 496 if (field->form_control_type() == ASCIIToUTF16("select-one")) { | 507 if (field->form_control_type() == ASCIIToUTF16("select-one")) { |
| 497 // TODO(isherman): <select> fields don't support |is_autofilled()|. Since | 508 // TODO(isherman): <select> fields don't support |is_autofilled()|. Since |
| 498 // this is heavily relied upon by our metrics, we just don't log anything | 509 // this is heavily relied upon by our metrics, we just don't log anything |
| 499 // for all <select> fields. Better to have less data than misleading data. | 510 // for all <select> fields. Better to have less data than misleading data. |
| 500 continue; | 511 continue; |
| 501 } | 512 } |
| 502 | 513 |
| 503 // Log various quality metrics. | 514 // Log various quality metrics. |
| 504 metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED); | 515 metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED); |
| 505 if (field_types.find(EMPTY_TYPE) == field_types.end() && | 516 if (field_types.find(EMPTY_TYPE) == field_types.end() && |
| 506 field_types.find(UNKNOWN_TYPE) == field_types.end()) { | 517 field_types.find(UNKNOWN_TYPE) == field_types.end()) { |
| 507 if (field->is_autofilled()) { | 518 if (field->is_autofilled()) { |
| 508 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED); | 519 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED); |
| 509 } else { | 520 } else { |
| 510 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED); | 521 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED); |
| 511 | 522 |
| 512 AutoFillFieldType heuristic_type = cached_upload_form_structure? | 523 AutoFillFieldType heuristic_type = cached_submitted_form? |
| 513 cached_upload_form_structure->field(i)->heuristic_type() : | 524 cached_submitted_form->field(i)->heuristic_type() : |
| 514 UNKNOWN_TYPE; | 525 UNKNOWN_TYPE; |
| 515 if (heuristic_type == UNKNOWN_TYPE) | 526 if (heuristic_type == UNKNOWN_TYPE) |
| 516 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_UNKNOWN); | 527 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_UNKNOWN); |
| 517 else if (field_types.count(heuristic_type)) | 528 else if (field_types.count(heuristic_type)) |
| 518 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MATCH); | 529 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MATCH); |
| 519 else | 530 else |
| 520 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MISMATCH); | 531 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MISMATCH); |
| 521 | 532 |
| 522 AutoFillFieldType server_type = cached_upload_form_structure? | 533 AutoFillFieldType server_type = cached_submitted_form? |
| 523 cached_upload_form_structure->field(i)->server_type() : | 534 cached_submitted_form->field(i)->server_type() : |
| 524 NO_SERVER_DATA; | 535 NO_SERVER_DATA; |
| 525 if (server_type == NO_SERVER_DATA) | 536 if (server_type == NO_SERVER_DATA) |
| 526 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_UNKNOWN); | 537 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_UNKNOWN); |
| 527 else if (field_types.count(server_type)) | 538 else if (field_types.count(server_type)) |
| 528 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MATCH); | 539 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MATCH); |
| 529 else | 540 else |
| 530 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MISMATCH); | 541 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MISMATCH); |
| 531 } | 542 } |
| 532 | 543 |
| 533 | |
| 534 // TODO(isherman): Other things we might want to log here: | 544 // TODO(isherman): Other things we might want to log here: |
| 535 // * Per Vadim's email, a combination of (1) whether heuristics fired, | 545 // * Per Vadim's email, a combination of (1) whether heuristics fired, |
| 536 // (2) whether the server returned something interesting, (3) whether | 546 // (2) whether the server returned something interesting, (3) whether |
| 537 // the user filled the field | 547 // the user filled the field |
| 538 // * Whether the server type matches the heursitic type | 548 // * Whether the server type matches the heursitic type |
| 539 // - Perhaps only if at least one of the types is not unknown/no data. | 549 // - Perhaps only if at least one of the types is not unknown/no data. |
| 540 } | 550 } |
| 541 } | 551 } |
| 542 } | 552 } |
| 543 | 553 |
| 544 void AutoFillManager::HandleSubmit() { | 554 void AutoFillManager::ImportFormData(const FormStructure& submitted_form) { |
| 545 // If there wasn't enough data to import then we don't want to send an upload | 555 std::vector<const FormStructure*> import; |
| 546 // to the server. | 556 import.push_back(&submitted_form); |
| 547 // TODO(jhawkins): Import form data from |form_structures_|. That will | |
| 548 // require querying the FormManager for updated field values. | |
| 549 std::vector<FormStructure*> import; | |
| 550 import.push_back(upload_form_structure_.get()); | |
| 551 if (!personal_data_->ImportFormData(import)) | 557 if (!personal_data_->ImportFormData(import)) |
| 552 return; | 558 return; |
| 553 | 559 |
| 554 // Did we get credit card info? | 560 // Did we get credit card info? |
| 555 AutoFillProfile* profile; | 561 AutoFillProfile* profile; |
| 556 CreditCard* credit_card; | 562 CreditCard* credit_card; |
| 557 personal_data_->GetImportedFormData(&profile, &credit_card); | 563 personal_data_->GetImportedFormData(&profile, &credit_card); |
| 558 | 564 |
| 559 if (!credit_card) { | 565 // If credit card information was submitted, show an infobar to offer to save |
| 560 UploadFormData(); | 566 // it. |
| 561 return; | 567 if (credit_card && tab_contents_) { |
| 562 } | |
| 563 | |
| 564 // Show an infobar to offer to save the credit card info. | |
| 565 if (tab_contents_) { | |
| 566 tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_, | 568 tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_, |
| 567 this)); | 569 this)); |
| 568 } | 570 } |
| 569 } | 571 } |
| 570 | 572 |
| 571 void AutoFillManager::UploadFormData() { | 573 void AutoFillManager::UploadFormData(const FormStructure& submitted_form) { |
| 572 if (!disable_download_manager_requests_ && upload_form_structure_.get()) { | 574 if (!disable_download_manager_requests_) { |
| 573 bool was_autofilled = false; | 575 bool was_autofilled = false; |
| 574 // Check if the form among last 3 forms that were auto-filled. | 576 // Check if the form among last 3 forms that were auto-filled. |
| 575 // Clear older signatures. | 577 // Clear older signatures. |
| 576 std::list<std::string>::iterator it; | 578 std::list<std::string>::iterator it; |
| 577 int total_form_checked = 0; | 579 int total_form_checked = 0; |
| 578 for (it = autofilled_forms_signatures_.begin(); | 580 for (it = autofilled_forms_signatures_.begin(); |
| 579 it != autofilled_forms_signatures_.end() && total_form_checked < 3; | 581 it != autofilled_forms_signatures_.end() && total_form_checked < 3; |
| 580 ++it, ++total_form_checked) { | 582 ++it, ++total_form_checked) { |
| 581 if (*it == upload_form_structure_->FormSignature()) | 583 if (*it == submitted_form.FormSignature()) |
| 582 was_autofilled = true; | 584 was_autofilled = true; |
| 583 } | 585 } |
| 584 // Remove outdated form signatures. | 586 // Remove outdated form signatures. |
| 585 if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) { | 587 if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) { |
| 586 autofilled_forms_signatures_.erase(it, | 588 autofilled_forms_signatures_.erase(it, |
| 587 autofilled_forms_signatures_.end()); | 589 autofilled_forms_signatures_.end()); |
| 588 } | 590 } |
| 589 download_manager_.StartUploadRequest(*(upload_form_structure_.get()), | 591 download_manager_.StartUploadRequest(submitted_form, was_autofilled); |
| 590 was_autofilled); | |
| 591 } | 592 } |
| 592 } | 593 } |
| 593 | 594 |
| 594 void AutoFillManager::Reset() { | 595 void AutoFillManager::Reset() { |
| 595 upload_form_structure_.reset(); | |
| 596 form_structures_.reset(); | 596 form_structures_.reset(); |
| 597 } | 597 } |
| 598 | 598 |
| 599 void AutoFillManager::OnInfoBarClosed(bool should_save) { | 599 void AutoFillManager::OnInfoBarClosed(bool should_save) { |
| 600 if (should_save) | 600 if (should_save) |
| 601 personal_data_->SaveImportedCreditCard(); | 601 personal_data_->SaveImportedCreditCard(); |
| 602 UploadFormData(); | |
| 603 } | 602 } |
| 604 | 603 |
| 605 AutoFillManager::AutoFillManager() | 604 AutoFillManager::AutoFillManager() |
| 606 : tab_contents_(NULL), | 605 : tab_contents_(NULL), |
| 607 personal_data_(NULL), | 606 personal_data_(NULL), |
| 608 download_manager_(NULL), | 607 download_manager_(NULL), |
| 609 disable_download_manager_requests_(true), | 608 disable_download_manager_requests_(true), |
| 610 metric_logger_(new AutoFillMetrics), | 609 metric_logger_(new AutoFillMetrics), |
| 611 cc_infobar_(NULL) { | 610 cc_infobar_(NULL) { |
| 612 } | 611 } |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 886 return std::string(); | 885 return std::string(); |
| 887 | 886 |
| 888 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); | 887 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); |
| 889 if (iter == id_guid_map_.end()) { | 888 if (iter == id_guid_map_.end()) { |
| 890 NOTREACHED(); | 889 NOTREACHED(); |
| 891 return std::string(); | 890 return std::string(); |
| 892 } | 891 } |
| 893 | 892 |
| 894 return iter->second; | 893 return iter->second; |
| 895 } | 894 } |
| OLD | NEW |