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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
212 if (!upload_form_structure_->ShouldBeParsed(true)) | 212 if (!upload_form_structure_->ShouldBeParsed(true)) |
213 return; | 213 return; |
214 | 214 |
215 FormStructure* cached_upload_form_structure = NULL; | 215 FormStructure* cached_upload_form_structure = NULL; |
216 AutoFillField* ignored; | 216 AutoFillField* ignored; |
217 if (!FindCachedFormAndField(form, form.fields.front(), | 217 if (!FindCachedFormAndField(form, form.fields.front(), |
218 &cached_upload_form_structure, &ignored)) { | 218 &cached_upload_form_structure, &ignored)) { |
219 cached_upload_form_structure = NULL; | 219 cached_upload_form_structure = NULL; |
220 } | 220 } |
221 | 221 |
222 DeterminePossibleFieldTypesForUpload(cached_upload_form_structure); | 222 std::string data_present = DeterminePossibleFieldTypesForUpload( |
| 223 cached_upload_form_structure); |
223 // TODO(isherman): Consider uploading to server here rather than in | 224 // TODO(isherman): Consider uploading to server here rather than in |
224 // HandleSubmit(). | 225 // HandleSubmit(). |
225 | 226 |
226 if (!upload_form_structure_->IsAutoFillable(true)) | 227 if (!upload_form_structure_->IsAutoFillable(true)) |
227 return; | 228 return; |
228 | 229 |
229 HandleSubmit(); | 230 HandleSubmit(data_present); |
230 } | 231 } |
231 | 232 |
232 void AutoFillManager::OnFormsSeen(const std::vector<FormData>& forms) { | 233 void AutoFillManager::OnFormsSeen(const std::vector<FormData>& forms) { |
233 if (!IsAutoFillEnabled()) | 234 if (!IsAutoFillEnabled()) |
234 return; | 235 return; |
235 | 236 |
236 ParseForms(forms); | 237 ParseForms(forms); |
237 } | 238 } |
238 | 239 |
239 void AutoFillManager::OnQueryFormFieldAutoFill( | 240 void AutoFillManager::OnQueryFormFieldAutoFill( |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
477 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) { | 478 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) { |
478 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); | 479 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); |
479 prefs->ClearPref(prefs::kFormAutofillEnabled); | 480 prefs->ClearPref(prefs::kFormAutofillEnabled); |
480 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); | 481 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); |
481 return enabled; | 482 return enabled; |
482 } | 483 } |
483 | 484 |
484 return prefs->GetBoolean(prefs::kAutoFillEnabled); | 485 return prefs->GetBoolean(prefs::kAutoFillEnabled); |
485 } | 486 } |
486 | 487 |
487 void AutoFillManager::DeterminePossibleFieldTypesForUpload( | 488 std::string AutoFillManager::DeterminePossibleFieldTypesForUpload( |
488 const FormStructure* cached_upload_form_structure) { | 489 const FormStructure* cached_upload_form_structure) { |
| 490 // Mark bits present for the upload for data_present field. |
| 491 std::vector<uint8> presence_bitfield; |
| 492 // Determine all of the field types that were autofilled. Pack bits into |
| 493 // |presence_bitfield|. The necessary size for |presence_bitfield| is |
| 494 // ceil((MAX_VALID_FIELD_TYPE + 7) / 8) bytes (uint8). |
| 495 presence_bitfield.resize((MAX_VALID_FIELD_TYPE + 0x7) >> 3); |
| 496 for (size_t i = 0; i < presence_bitfield.size(); ++i) |
| 497 presence_bitfield[i] = 0; |
| 498 |
489 for (size_t i = 0; i < upload_form_structure_->field_count(); i++) { | 499 for (size_t i = 0; i < upload_form_structure_->field_count(); i++) { |
490 const AutoFillField* field = upload_form_structure_->field(i); | 500 const AutoFillField* field = upload_form_structure_->field(i); |
491 FieldTypeSet field_types; | 501 FieldTypeSet field_types; |
492 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); | 502 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); |
493 DCHECK(!field_types.empty()); | |
494 upload_form_structure_->set_possible_types(i, field_types); | |
495 | 503 |
496 if (field->form_control_type() == ASCIIToUTF16("select-one")) { | 504 if (field->form_control_type() == ASCIIToUTF16("select-one")) { |
497 // TODO(isherman): <select> fields don't support |is_autofilled()|. Since | 505 // 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 | 506 // 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. | 507 // for all <select> fields. Better to have less data than misleading data. |
500 continue; | 508 } else { |
| 509 // Log various quality metrics. |
| 510 metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED); |
| 511 if (field_types.find(EMPTY_TYPE) == field_types.end() && |
| 512 field_types.find(UNKNOWN_TYPE) == field_types.end()) { |
| 513 if (field->is_autofilled()) { |
| 514 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED); |
| 515 } else { |
| 516 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED); |
| 517 |
| 518 AutoFillFieldType heuristic_type = cached_upload_form_structure? |
| 519 cached_upload_form_structure->field(i)->heuristic_type() : |
| 520 UNKNOWN_TYPE; |
| 521 if (heuristic_type == UNKNOWN_TYPE) |
| 522 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_UNKNOWN); |
| 523 else if (field_types.count(heuristic_type)) |
| 524 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MATCH); |
| 525 else |
| 526 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MISMATCH); |
| 527 |
| 528 AutoFillFieldType server_type = cached_upload_form_structure? |
| 529 cached_upload_form_structure->field(i)->server_type() : |
| 530 NO_SERVER_DATA; |
| 531 if (server_type == NO_SERVER_DATA) |
| 532 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_UNKNOWN); |
| 533 else if (field_types.count(server_type)) |
| 534 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MATCH); |
| 535 else |
| 536 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MISMATCH); |
| 537 } |
| 538 |
| 539 |
| 540 // TODO(isherman): Other things we might want to log here: |
| 541 // * Per Vadim's email, a combination of (1) whether heuristics fired, |
| 542 // (2) whether the server returned something interesting, (3) whether |
| 543 // the user filled the field |
| 544 // * Whether the server type matches the heursitic type |
| 545 // - Perhaps only if at least one of the types is not unknown/no data. |
| 546 } |
| 547 } |
| 548 DCHECK(!field_types.empty()); |
| 549 if (field_types.size() > 1) { |
| 550 // If there is more than one possibility, do not poison the crowd-sourced |
| 551 // data by returning UNKNOWN_TYPE. |
| 552 field_types.clear(); |
| 553 field_types.insert(UNKNOWN_TYPE); |
501 } | 554 } |
502 | 555 |
503 // Log various quality metrics. | 556 upload_form_structure_->set_possible_types(i, field_types); |
504 metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED); | 557 SetPresenceBit(*(field_types.begin()), &presence_bitfield); |
505 if (field_types.find(EMPTY_TYPE) == field_types.end() && | 558 } |
506 field_types.find(UNKNOWN_TYPE) == field_types.end()) { | |
507 if (field->is_autofilled()) { | |
508 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED); | |
509 } else { | |
510 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED); | |
511 | 559 |
512 AutoFillFieldType heuristic_type = cached_upload_form_structure? | 560 return ConvertPresenceBitsToString(presence_bitfield); |
513 cached_upload_form_structure->field(i)->heuristic_type() : | |
514 UNKNOWN_TYPE; | |
515 if (heuristic_type == UNKNOWN_TYPE) | |
516 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_UNKNOWN); | |
517 else if (field_types.count(heuristic_type)) | |
518 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MATCH); | |
519 else | |
520 metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MISMATCH); | |
521 | |
522 AutoFillFieldType server_type = cached_upload_form_structure? | |
523 cached_upload_form_structure->field(i)->server_type() : | |
524 NO_SERVER_DATA; | |
525 if (server_type == NO_SERVER_DATA) | |
526 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_UNKNOWN); | |
527 else if (field_types.count(server_type)) | |
528 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MATCH); | |
529 else | |
530 metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MISMATCH); | |
531 } | |
532 | |
533 | |
534 // TODO(isherman): Other things we might want to log here: | |
535 // * Per Vadim's email, a combination of (1) whether heuristics fired, | |
536 // (2) whether the server returned something interesting, (3) whether | |
537 // the user filled the field | |
538 // * Whether the server type matches the heursitic type | |
539 // - Perhaps only if at least one of the types is not unknown/no data. | |
540 } | |
541 } | |
542 } | 561 } |
543 | 562 |
544 void AutoFillManager::HandleSubmit() { | 563 void AutoFillManager::HandleSubmit(std::string const& data_present) { |
545 // If there wasn't enough data to import then we don't want to send an upload | 564 // If there wasn't enough data to import then we don't want to send an upload |
546 // to the server. | 565 // to the server. |
547 // TODO(jhawkins): Import form data from |form_structures_|. That will | 566 // TODO(jhawkins): Import form data from |form_structures_|. That will |
548 // require querying the FormManager for updated field values. | 567 // require querying the FormManager for updated field values. |
549 std::vector<FormStructure*> import; | 568 std::vector<FormStructure*> import; |
550 import.push_back(upload_form_structure_.get()); | 569 import.push_back(upload_form_structure_.get()); |
551 if (!personal_data_->ImportFormData(import)) | 570 if (!personal_data_->ImportFormData(import)) |
552 return; | 571 return; |
553 | 572 |
554 // Did we get credit card info? | 573 // Did we get credit card info? |
555 AutoFillProfile* profile; | 574 AutoFillProfile* profile; |
556 CreditCard* credit_card; | 575 CreditCard* credit_card; |
557 personal_data_->GetImportedFormData(&profile, &credit_card); | 576 personal_data_->GetImportedFormData(&profile, &credit_card); |
558 | 577 |
559 if (!credit_card) { | 578 if (!credit_card) { |
560 UploadFormData(); | 579 data_autofilled_.clear(); |
| 580 UploadFormData(data_present); |
561 return; | 581 return; |
| 582 } else { |
| 583 data_autofilled_ = data_present; |
562 } | 584 } |
563 | 585 |
564 // Show an infobar to offer to save the credit card info. | 586 // Show an infobar to offer to save the credit card info. |
565 if (tab_contents_) { | 587 if (tab_contents_) { |
566 tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_, | 588 tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_, |
567 this)); | 589 this)); |
568 } | 590 } |
569 } | 591 } |
570 | 592 |
571 void AutoFillManager::UploadFormData() { | 593 void AutoFillManager::UploadFormData(std::string const& data_present) { |
572 if (!disable_download_manager_requests_ && upload_form_structure_.get()) { | 594 if (!disable_download_manager_requests_ && upload_form_structure_.get()) { |
573 bool was_autofilled = false; | 595 bool was_autofilled = false; |
574 // Check if the form among last 3 forms that were auto-filled. | 596 // Check if the form among last 3 forms that were auto-filled. |
575 // Clear older signatures. | 597 // Clear older signatures. |
576 std::list<std::string>::iterator it; | 598 std::list<std::string>::iterator it; |
577 int total_form_checked = 0; | 599 int total_form_checked = 0; |
578 for (it = autofilled_forms_signatures_.begin(); | 600 for (it = autofilled_forms_signatures_.begin(); |
579 it != autofilled_forms_signatures_.end() && total_form_checked < 3; | 601 it != autofilled_forms_signatures_.end() && total_form_checked < 3; |
580 ++it, ++total_form_checked) { | 602 ++it, ++total_form_checked) { |
581 if (*it == upload_form_structure_->FormSignature()) | 603 if (*it == upload_form_structure_->FormSignature()) { |
582 was_autofilled = true; | 604 was_autofilled = true; |
| 605 } |
583 } | 606 } |
584 // Remove outdated form signatures. | 607 // Remove outdated form signatures. |
585 if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) { | 608 if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) { |
586 autofilled_forms_signatures_.erase(it, | 609 autofilled_forms_signatures_.erase(it, |
587 autofilled_forms_signatures_.end()); | 610 autofilled_forms_signatures_.end()); |
588 } | 611 } |
589 download_manager_.StartUploadRequest(*(upload_form_structure_.get()), | 612 download_manager_.StartUploadRequest(*(upload_form_structure_.get()), |
590 was_autofilled); | 613 was_autofilled, |
| 614 data_present.c_str()); |
591 } | 615 } |
592 } | 616 } |
593 | 617 |
594 void AutoFillManager::Reset() { | 618 void AutoFillManager::Reset() { |
595 upload_form_structure_.reset(); | 619 upload_form_structure_.reset(); |
596 form_structures_.reset(); | 620 form_structures_.reset(); |
597 } | 621 } |
598 | 622 |
| 623 void AutoFillManager::SetPresenceBit(AutoFillFieldType field_type, |
| 624 std::vector<uint8>* bitfield) { |
| 625 DCHECK(bitfield); |
| 626 DCHECK(bitfield->size() > (static_cast<size_t>(field_type) >> 3)); |
| 627 // Set bit in the bitfield: byte |field_type| / 8, bit in byte |
| 628 // |field_type| % 8 from the left. |
| 629 (*bitfield)[field_type >> 3] |= (0x80 >> (field_type & 7)); |
| 630 } |
| 631 |
| 632 std::string AutoFillManager::ConvertPresenceBitsToString( |
| 633 std::vector<uint8> const& bitfield) { |
| 634 std::string present_data; |
| 635 present_data.reserve(bitfield.size() * 2 + 1); |
| 636 // Skip leading zeroes. If all mask is 0 - return empty string. |
| 637 size_t data_end = bitfield.size(); |
| 638 for (; data_end > 0 && !bitfield[data_end - 1]; --data_end) { |
| 639 } |
| 640 // Print all non-zero bytes into the string. |
| 641 for (size_t i = 0; i < data_end; ++i) { |
| 642 base::StringAppendF(&present_data, "%02x", bitfield[i]); |
| 643 } |
| 644 return present_data; |
| 645 } |
| 646 |
599 void AutoFillManager::OnInfoBarClosed(bool should_save) { | 647 void AutoFillManager::OnInfoBarClosed(bool should_save) { |
600 if (should_save) | 648 if (should_save) |
601 personal_data_->SaveImportedCreditCard(); | 649 personal_data_->SaveImportedCreditCard(); |
602 UploadFormData(); | 650 UploadFormData(data_autofilled_); |
603 } | 651 } |
604 | 652 |
605 AutoFillManager::AutoFillManager() | 653 AutoFillManager::AutoFillManager() |
606 : tab_contents_(NULL), | 654 : tab_contents_(NULL), |
607 personal_data_(NULL), | 655 personal_data_(NULL), |
608 download_manager_(NULL), | 656 download_manager_(NULL), |
609 disable_download_manager_requests_(true), | 657 disable_download_manager_requests_(true), |
610 metric_logger_(new AutoFillMetrics), | 658 metric_logger_(new AutoFillMetrics), |
611 cc_infobar_(NULL) { | 659 cc_infobar_(NULL) { |
612 } | 660 } |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 return std::string(); | 934 return std::string(); |
887 | 935 |
888 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); | 936 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); |
889 if (iter == id_guid_map_.end()) { | 937 if (iter == id_guid_map_.end()) { |
890 NOTREACHED(); | 938 NOTREACHED(); |
891 return std::string(); | 939 return std::string(); |
892 } | 940 } |
893 | 941 |
894 return iter->second; | 942 return iter->second; |
895 } | 943 } |
OLD | NEW |