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

Side by Side Diff: components/autofill/core/browser/form_structure.cc

Issue 23033016: Remove autocheckout code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixing compile failures and tests. Created 7 years, 4 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 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/form_structure.h" 5 #include "components/autofill/core/browser/form_structure.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/basictypes.h" 9 #include "base/basictypes.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/sha1.h" 13 #include "base/sha1.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
18 #include "base/time/time.h" 18 #include "base/time/time.h"
19 #include "components/autofill/content/browser/autocheckout_page_meta_data.h"
20 #include "components/autofill/core/browser/autofill_metrics.h" 19 #include "components/autofill/core/browser/autofill_metrics.h"
21 #include "components/autofill/core/browser/autofill_type.h" 20 #include "components/autofill/core/browser/autofill_type.h"
22 #include "components/autofill/core/browser/autofill_xml_parser.h" 21 #include "components/autofill/core/browser/autofill_xml_parser.h"
23 #include "components/autofill/core/browser/field_types.h" 22 #include "components/autofill/core/browser/field_types.h"
24 #include "components/autofill/core/browser/form_field.h" 23 #include "components/autofill/core/browser/form_field.h"
25 #include "components/autofill/core/common/autofill_constants.h" 24 #include "components/autofill/core/common/autofill_constants.h"
26 #include "components/autofill/core/common/form_data.h" 25 #include "components/autofill/core/common/form_data.h"
27 #include "components/autofill/core/common/form_data_predictions.h" 26 #include "components/autofill/core/common/form_data_predictions.h"
28 #include "components/autofill/core/common/form_field_data.h" 27 #include "components/autofill/core/common/form_field_data.h"
29 #include "components/autofill/core/common/form_field_data_predictions.h" 28 #include "components/autofill/core/common/form_field_data_predictions.h"
(...skipping 11 matching lines...) Expand all
41 const char kAttributeAutofillType[] = "autofilltype"; 40 const char kAttributeAutofillType[] = "autofilltype";
42 const char kAttributeClientVersion[] = "clientversion"; 41 const char kAttributeClientVersion[] = "clientversion";
43 const char kAttributeDataPresent[] = "datapresent"; 42 const char kAttributeDataPresent[] = "datapresent";
44 const char kAttributeFieldID[] = "fieldid"; 43 const char kAttributeFieldID[] = "fieldid";
45 const char kAttributeFieldType[] = "fieldtype"; 44 const char kAttributeFieldType[] = "fieldtype";
46 const char kAttributeFormSignature[] = "formsignature"; 45 const char kAttributeFormSignature[] = "formsignature";
47 const char kAttributeName[] = "name"; 46 const char kAttributeName[] = "name";
48 const char kAttributeSignature[] = "signature"; 47 const char kAttributeSignature[] = "signature";
49 const char kAttributeUrlprefixSignature[] = "urlprefixsignature"; 48 const char kAttributeUrlprefixSignature[] = "urlprefixsignature";
50 const char kAcceptedFeaturesExperiment[] = "e"; // e=experiments 49 const char kAcceptedFeaturesExperiment[] = "e"; // e=experiments
51 const char kAcceptedFeaturesAutocheckoutExperiment[] = "a,e"; // a=autocheckout
52 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)"; 50 const char kClientVersion[] = "6.1.1715.1442/en (GGLL)";
53 const char kXMLDeclaration[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; 51 const char kXMLDeclaration[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
54 const char kXMLElementAutofillQuery[] = "autofillquery"; 52 const char kXMLElementAutofillQuery[] = "autofillquery";
55 const char kXMLElementAutofillUpload[] = "autofillupload"; 53 const char kXMLElementAutofillUpload[] = "autofillupload";
56 const char kXMLElementFieldAssignments[] = "fieldassignments"; 54 const char kXMLElementFieldAssignments[] = "fieldassignments";
57 const char kXMLElementField[] = "field"; 55 const char kXMLElementField[] = "field";
58 const char kXMLElementFields[] = "fields"; 56 const char kXMLElementFields[] = "fields";
59 const char kXMLElementForm[] = "form"; 57 const char kXMLElementForm[] = "form";
60 const char kBillingMode[] = "billing"; 58 const char kBillingMode[] = "billing";
61 const char kShippingMode[] = "shipping"; 59 const char kShippingMode[] = "shipping";
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 if (status != U_ZERO_ERROR) { 315 if (status != U_ZERO_ERROR) {
318 DVLOG(1) << "Couldn't strip digits in " << UTF16ToUTF8(input); 316 DVLOG(1) << "Couldn't strip digits in " << UTF16ToUTF8(input);
319 return UTF16ToUTF8(input); 317 return UTF16ToUTF8(input);
320 } 318 }
321 319
322 return return_string; 320 return return_string;
323 } 321 }
324 322
325 } // namespace 323 } // namespace
326 324
327 FormStructure::FormStructure(const FormData& form, 325 FormStructure::FormStructure(const FormData& form)
328 const std::string& autocheckout_url_prefix)
329 : form_name_(form.name), 326 : form_name_(form.name),
330 source_url_(form.origin), 327 source_url_(form.origin),
331 target_url_(form.action), 328 target_url_(form.action),
332 autofill_count_(0), 329 autofill_count_(0),
333 active_field_count_(0), 330 active_field_count_(0),
334 upload_required_(USE_UPLOAD_RATES), 331 upload_required_(USE_UPLOAD_RATES),
335 server_experiment_id_("no server response"), 332 server_experiment_id_("no server response"),
336 has_author_specified_types_(false), 333 has_author_specified_types_(false) {
337 autocheckout_url_prefix_(autocheckout_url_prefix),
338 filled_by_autocheckout_(false) {
339 // Copy the form fields. 334 // Copy the form fields.
340 std::map<base::string16, size_t> unique_names; 335 std::map<base::string16, size_t> unique_names;
341 for (std::vector<FormFieldData>::const_iterator field = 336 for (std::vector<FormFieldData>::const_iterator field =
342 form.fields.begin(); 337 form.fields.begin();
343 field != form.fields.end(); field++) { 338 field != form.fields.end(); field++) {
344 339
345 if (!ShouldSkipField(*field)) { 340 if (!ShouldSkipField(*field)) {
346 // Add all supported form fields (including with empty names) to the 341 // Add all supported form fields (including with empty names) to the
347 // signature. This is a requirement for Autofill servers. 342 // signature. This is a requirement for Autofill servers.
348 form_signature_field_names_.append("&"); 343 form_signature_field_names_.append("&");
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 encoded_xml->clear(); 483 encoded_xml->clear();
489 encoded_signatures->clear(); 484 encoded_signatures->clear();
490 encoded_signatures->reserve(forms.size()); 485 encoded_signatures->reserve(forms.size());
491 486
492 // Set up the <autofillquery> element and attributes. 487 // Set up the <autofillquery> element and attributes.
493 buzz::XmlElement autofill_request_xml( 488 buzz::XmlElement autofill_request_xml(
494 (buzz::QName(kXMLElementAutofillQuery))); 489 (buzz::QName(kXMLElementAutofillQuery)));
495 autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), 490 autofill_request_xml.SetAttr(buzz::QName(kAttributeClientVersion),
496 kClientVersion); 491 kClientVersion);
497 492
498 // autocheckout_url_prefix tells the Autofill server where the forms in the
499 // request came from, and the the Autofill server checks internal status and
500 // decide to enable Autocheckout or not and may return Autocheckout related
501 // data in the response accordingly.
502 // There is no page/frame level object associated with FormStructure that
503 // we could extract URL prefix from. But, all the forms should come from the
504 // same frame, so they should have the same Autocheckout URL prefix. Thus we
505 // use URL prefix from the first form with Autocheckout enabled.
506 std::string autocheckout_url_prefix;
507
508 // Some badly formatted web sites repeat forms - detect that and encode only 493 // Some badly formatted web sites repeat forms - detect that and encode only
509 // one form as returned data would be the same for all the repeated forms. 494 // one form as returned data would be the same for all the repeated forms.
510 std::set<std::string> processed_forms; 495 std::set<std::string> processed_forms;
511 for (ScopedVector<FormStructure>::const_iterator it = forms.begin(); 496 for (ScopedVector<FormStructure>::const_iterator it = forms.begin();
512 it != forms.end(); 497 it != forms.end();
513 ++it) { 498 ++it) {
514 std::string signature((*it)->FormSignature()); 499 std::string signature((*it)->FormSignature());
515 if (processed_forms.find(signature) != processed_forms.end()) 500 if (processed_forms.find(signature) != processed_forms.end())
516 continue; 501 continue;
517 processed_forms.insert(signature); 502 processed_forms.insert(signature);
518 scoped_ptr<buzz::XmlElement> encompassing_xml_element( 503 scoped_ptr<buzz::XmlElement> encompassing_xml_element(
519 new buzz::XmlElement(buzz::QName(kXMLElementForm))); 504 new buzz::XmlElement(buzz::QName(kXMLElementForm)));
520 encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature), 505 encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature),
521 signature); 506 signature);
522 507
523 if (!(*it)->EncodeFormRequest(FormStructure::QUERY, 508 if (!(*it)->EncodeFormRequest(FormStructure::QUERY,
524 encompassing_xml_element.get())) 509 encompassing_xml_element.get()))
525 continue; // Malformed form, skip it. 510 continue; // Malformed form, skip it.
526 511
527 if ((*it)->IsAutocheckoutEnabled()) {
528 if (autocheckout_url_prefix.empty()) {
529 autocheckout_url_prefix = (*it)->autocheckout_url_prefix_;
530 } else {
531 // Making sure all the forms in the request has the same url_prefix.
532 DCHECK_EQ(autocheckout_url_prefix, (*it)->autocheckout_url_prefix_);
533 }
534 }
535
536 autofill_request_xml.AddElement(encompassing_xml_element.release()); 512 autofill_request_xml.AddElement(encompassing_xml_element.release());
537 encoded_signatures->push_back(signature); 513 encoded_signatures->push_back(signature);
538 } 514 }
539 515
540 if (!encoded_signatures->size()) 516 if (!encoded_signatures->size())
541 return false; 517 return false;
542 518
543 if (autocheckout_url_prefix.empty()) { 519 autofill_request_xml.SetAttr(buzz::QName(kAttributeAcceptedFeatures),
544 autofill_request_xml.SetAttr(buzz::QName(kAttributeAcceptedFeatures), 520 kAcceptedFeaturesExperiment);
545 kAcceptedFeaturesExperiment);
546 } else {
547 autofill_request_xml.SetAttr(buzz::QName(kAttributeAcceptedFeatures),
548 kAcceptedFeaturesAutocheckoutExperiment);
549 autofill_request_xml.SetAttr(buzz::QName(kAttributeUrlprefixSignature),
550 Hash64Bit(autocheckout_url_prefix));
551 }
552 521
553 // Obtain the XML structure as a string. 522 // Obtain the XML structure as a string.
554 *encoded_xml = kXMLDeclaration; 523 *encoded_xml = kXMLDeclaration;
555 *encoded_xml += autofill_request_xml.Str().c_str(); 524 *encoded_xml += autofill_request_xml.Str().c_str();
556 525
557 return true; 526 return true;
558 } 527 }
559 528
560 // static 529 // static
561 void FormStructure::ParseQueryResponse( 530 void FormStructure::ParseQueryResponse(
562 const std::string& response_xml, 531 const std::string& response_xml,
563 const std::vector<FormStructure*>& forms, 532 const std::vector<FormStructure*>& forms,
564 autofill::AutocheckoutPageMetaData* page_meta_data,
565 const AutofillMetrics& metric_logger) { 533 const AutofillMetrics& metric_logger) {
566 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_RECEIVED); 534 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_RECEIVED);
567 535
568 // Parse the field types from the server response to the query. 536 // Parse the field types from the server response to the query.
569 std::vector<AutofillServerFieldInfo> field_infos; 537 std::vector<AutofillServerFieldInfo> field_infos;
570 UploadRequired upload_required; 538 UploadRequired upload_required;
571 std::string experiment_id; 539 std::string experiment_id;
572 AutofillQueryXmlParser parse_handler(&field_infos, 540 AutofillQueryXmlParser parse_handler(&field_infos,
573 &upload_required, 541 &upload_required,
574 &experiment_id, 542 &experiment_id);
575 page_meta_data);
576 buzz::XmlParser parser(&parse_handler); 543 buzz::XmlParser parser(&parse_handler);
577 parser.Parse(response_xml.c_str(), response_xml.length(), true); 544 parser.Parse(response_xml.c_str(), response_xml.length(), true);
578 if (!parse_handler.succeeded()) 545 if (!parse_handler.succeeded())
579 return; 546 return;
580 547
581 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED); 548 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED);
582 metric_logger.LogServerExperimentIdForQuery(experiment_id); 549 metric_logger.LogServerExperimentIdForQuery(experiment_id);
583 550
584 bool heuristics_detected_fillable_field = false; 551 bool heuristics_detected_fillable_field = false;
585 bool query_response_overrode_heuristics = false; 552 bool query_response_overrode_heuristics = false;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 host = source_url_.host(); 652 host = source_url_.host();
686 } 653 }
687 654
688 std::string form_string = scheme + "://" + host + "&" + 655 std::string form_string = scheme + "://" + host + "&" +
689 UTF16ToUTF8(form_name_) + 656 UTF16ToUTF8(form_name_) +
690 form_signature_field_names_; 657 form_signature_field_names_;
691 658
692 return Hash64Bit(form_string); 659 return Hash64Bit(form_string);
693 } 660 }
694 661
695 bool FormStructure::IsAutocheckoutEnabled() const {
696 return !autocheckout_url_prefix_.empty();
697 }
698
699 bool FormStructure::ShouldSkipField(const FormFieldData& field) const { 662 bool FormStructure::ShouldSkipField(const FormFieldData& field) const {
700 return (field.is_checkable || field.form_control_type == "password") && 663 return (field.is_checkable || field.form_control_type == "password");
701 !IsAutocheckoutEnabled();
702 } 664 }
703 665
704 size_t FormStructure::RequiredFillableFields() const { 666 size_t FormStructure::RequiredFillableFields() const {
705 return IsAutocheckoutEnabled() ? 0 : kRequiredAutofillFields; 667 return kRequiredAutofillFields;
706 } 668 }
Ilya Sherman 2013/08/27 18:57:57 nit: Seems reasonable to inline this method at thi
Raman Kakilate 2013/08/27 21:52:59 Done.
707 669
708 bool FormStructure::IsAutofillable(bool require_method_post) const { 670 bool FormStructure::IsAutofillable(bool require_method_post) const {
709 if (autofill_count() < RequiredFillableFields()) 671 if (autofill_count() < RequiredFillableFields())
710 return false; 672 return false;
711 673
712 return ShouldBeParsed(require_method_post); 674 return ShouldBeParsed(require_method_post);
713 } 675 }
714 676
715 void FormStructure::UpdateAutofillCount() { 677 void FormStructure::UpdateAutofillCount() {
716 autofill_count_ = 0; 678 autofill_count_ = 0;
717 for (std::vector<AutofillField*>::const_iterator iter = begin(); 679 for (std::vector<AutofillField*>::const_iterator iter = begin();
718 iter != end(); ++iter) { 680 iter != end(); ++iter) {
719 AutofillField* field = *iter; 681 AutofillField* field = *iter;
720 if (field && field->IsFieldFillable()) 682 if (field && field->IsFieldFillable())
721 ++autofill_count_; 683 ++autofill_count_;
722 } 684 }
723 } 685 }
724 686
725 bool FormStructure::ShouldBeParsed(bool require_method_post) const { 687 bool FormStructure::ShouldBeParsed(bool require_method_post) const {
726 if (active_field_count() < RequiredFillableFields()) 688 if (active_field_count() < RequiredFillableFields())
727 return false; 689 return false;
728 690
729 // Rule out http(s)://*/search?... 691 // Rule out http(s)://*/search?...
730 // e.g. http://www.google.com/search?q=... 692 // e.g. http://www.google.com/search?q=...
731 // http://search.yahoo.com/search?p=... 693 // http://search.yahoo.com/search?p=...
732 if (target_url_.path() == "/search") 694 if (target_url_.path() == "/search")
733 return false; 695 return false;
734 696
735 if (!IsAutocheckoutEnabled()) { 697 bool has_text_field = false;
736 // Make sure there is at least one text field when Autocheckout is 698 for (std::vector<AutofillField*>::const_iterator it = begin();
737 // not enabled. 699 it != end() && !has_text_field; ++it) {
738 bool has_text_field = false; 700 has_text_field |= (*it)->form_control_type != "select-one";
739 for (std::vector<AutofillField*>::const_iterator it = begin();
740 it != end() && !has_text_field; ++it) {
741 has_text_field |= (*it)->form_control_type != "select-one";
742 }
743 if (!has_text_field)
744 return false;
745 } 701 }
702 if (!has_text_field)
703 return false;
746 704
747 return !require_method_post || (method_ == POST); 705 return !require_method_post || (method_ == POST);
748 } 706 }
749 707
750 bool FormStructure::ShouldBeCrowdsourced() const { 708 bool FormStructure::ShouldBeCrowdsourced() const {
751 // Allow all forms in Autocheckout flow to be crowdsourced. 709 return !has_author_specified_types_ && ShouldBeParsed(true);
752 return (!has_author_specified_types_ && ShouldBeParsed(true)) ||
753 IsAutocheckoutEnabled();
754 } 710 }
755 711
756 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { 712 void FormStructure::UpdateFromCache(const FormStructure& cached_form) {
757 // Map from field signatures to cached fields. 713 // Map from field signatures to cached fields.
758 std::map<std::string, const AutofillField*> cached_fields; 714 std::map<std::string, const AutofillField*> cached_fields;
759 for (size_t i = 0; i < cached_form.field_count(); ++i) { 715 for (size_t i = 0; i < cached_form.field_count(); ++i) {
760 const AutofillField* field = cached_form.field(i); 716 const AutofillField* field = cached_form.field(i);
761 cached_fields[field->FieldSignature()] = field; 717 cached_fields[field->FieldSignature()] = field;
762 } 718 }
763 719
(...skipping 11 matching lines...) Expand all
775 field->value = base::string16(); 731 field->value = base::string16();
776 } 732 }
777 733
778 field->set_heuristic_type(cached_field->second->heuristic_type()); 734 field->set_heuristic_type(cached_field->second->heuristic_type());
779 field->set_server_type(cached_field->second->server_type()); 735 field->set_server_type(cached_field->second->server_type());
780 } 736 }
781 } 737 }
782 738
783 UpdateAutofillCount(); 739 UpdateAutofillCount();
784 740
785 filled_by_autocheckout_ = cached_form.filled_by_autocheckout();
786 server_experiment_id_ = cached_form.server_experiment_id(); 741 server_experiment_id_ = cached_form.server_experiment_id();
787 742
788 // The form signature should match between query and upload requests to the 743 // The form signature should match between query and upload requests to the
789 // server. On many websites, form elements are dynamically added, removed, or 744 // server. On many websites, form elements are dynamically added, removed, or
790 // rearranged via JavaScript between page load and form submission, so we 745 // rearranged via JavaScript between page load and form submission, so we
791 // copy over the |form_signature_field_names_| corresponding to the query 746 // copy over the |form_signature_field_names_| corresponding to the query
792 // request. 747 // request.
793 DCHECK_EQ(cached_form.form_name_, form_name_); 748 DCHECK_EQ(cached_form.form_name_, form_name_);
794 DCHECK_EQ(cached_form.source_url_, source_url_); 749 DCHECK_EQ(cached_form.source_url_, source_url_);
795 DCHECK_EQ(cached_form.target_url_, target_url_); 750 DCHECK_EQ(cached_form.target_url_, target_url_);
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 field != fields_.end(); ++field) { 1205 field != fields_.end(); ++field) {
1251 FieldTypeGroup field_type_group = (*field)->Type().group(); 1206 FieldTypeGroup field_type_group = (*field)->Type().group();
1252 if (field_type_group == CREDIT_CARD) 1207 if (field_type_group == CREDIT_CARD)
1253 (*field)->set_section((*field)->section() + "-cc"); 1208 (*field)->set_section((*field)->section() + "-cc");
1254 else 1209 else
1255 (*field)->set_section((*field)->section() + "-default"); 1210 (*field)->set_section((*field)->section() + "-default");
1256 } 1211 }
1257 } 1212 }
1258 1213
1259 } // namespace autofill 1214 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698