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

Side by Side Diff: chrome/browser/autofill/autofill_manager.cc

Issue 6213002: Propagate correct data to the Toolbar servers (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698