| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/form_structure.h" | 5 #include "chrome/browser/autofill/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" |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 return PHONE_HOME_NUMBER; | 216 return PHONE_HOME_NUMBER; |
| 217 | 217 |
| 218 if (autocomplete_type == "email") | 218 if (autocomplete_type == "email") |
| 219 return EMAIL_ADDRESS; | 219 return EMAIL_ADDRESS; |
| 220 | 220 |
| 221 return UNKNOWN_TYPE; | 221 return UNKNOWN_TYPE; |
| 222 } | 222 } |
| 223 | 223 |
| 224 } // namespace | 224 } // namespace |
| 225 | 225 |
| 226 FormStructure::FormStructure(const FormData& form) | 226 FormStructure::FormStructure(const FormData& form, |
| 227 std::string autocheckout_url_prefix) |
| 227 : form_name_(form.name), | 228 : form_name_(form.name), |
| 228 source_url_(form.origin), | 229 source_url_(form.origin), |
| 229 target_url_(form.action), | 230 target_url_(form.action), |
| 230 autofill_count_(0), | 231 autofill_count_(0), |
| 231 checkable_field_count_(0), | 232 checkable_field_count_(0), |
| 232 upload_required_(USE_UPLOAD_RATES), | 233 upload_required_(USE_UPLOAD_RATES), |
| 233 server_experiment_id_("no server response"), | 234 server_experiment_id_("no server response"), |
| 234 has_author_specified_types_(false), | 235 has_author_specified_types_(false), |
| 235 experimental_form_filling_enabled_( | 236 autocheckout_url_prefix_(autocheckout_url_prefix) { |
| 236 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 237 switches::kEnableExperimentalFormFilling)) { | |
| 238 // Copy the form fields. | 237 // Copy the form fields. |
| 239 std::map<string16, size_t> unique_names; | 238 std::map<string16, size_t> unique_names; |
| 240 for (std::vector<FormFieldData>::const_iterator field = | 239 for (std::vector<FormFieldData>::const_iterator field = |
| 241 form.fields.begin(); | 240 form.fields.begin(); |
| 242 field != form.fields.end(); field++) { | 241 field != form.fields.end(); field++) { |
| 243 // Skipping checkable elements when flag is not set, else these fields will | 242 // Skipping checkable elements when autocheckout is not enabled, else |
| 244 // interfere with existing field signatures with Autofill servers. | 243 // these fields will interfere with existing field signatures with Autofill |
| 245 // TODO(ramankk): Add checkable elements only on whitelisted pages | 244 // servers. |
| 246 if (!field->is_checkable || experimental_form_filling_enabled_) { | 245 if (!field->is_checkable || IsAutocheckoutEnabled()) { |
| 247 // Add all supported form fields (including with empty names) to the | 246 // Add all supported form fields (including with empty names) to the |
| 248 // signature. This is a requirement for Autofill servers. | 247 // signature. This is a requirement for Autofill servers. |
| 249 form_signature_field_names_.append("&"); | 248 form_signature_field_names_.append("&"); |
| 250 form_signature_field_names_.append(UTF16ToUTF8(field->name)); | 249 form_signature_field_names_.append(UTF16ToUTF8(field->name)); |
| 251 } | 250 } |
| 252 | 251 |
| 253 // Generate a unique name for this field by appending a counter to the name. | 252 // Generate a unique name for this field by appending a counter to the name. |
| 254 // Make sure to prepend the counter with a non-numeric digit so that we are | 253 // Make sure to prepend the counter with a non-numeric digit so that we are |
| 255 // guaranteed to avoid collisions. | 254 // guaranteed to avoid collisions. |
| 256 if (!unique_names.count(field->name)) | 255 if (!unique_names.count(field->name)) |
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 host = source_url_.host(); | 543 host = source_url_.host(); |
| 545 } | 544 } |
| 546 | 545 |
| 547 std::string form_string = scheme + "://" + host + "&" + | 546 std::string form_string = scheme + "://" + host + "&" + |
| 548 UTF16ToUTF8(form_name_) + | 547 UTF16ToUTF8(form_name_) + |
| 549 form_signature_field_names_; | 548 form_signature_field_names_; |
| 550 | 549 |
| 551 return Hash64Bit(form_string); | 550 return Hash64Bit(form_string); |
| 552 } | 551 } |
| 553 | 552 |
| 553 bool FormStructure::IsAutocheckoutEnabled() const { |
| 554 return !autocheckout_url_prefix_.empty(); |
| 555 } |
| 556 |
| 557 size_t FormStructure::RequiredFillableFields() const { |
| 558 return IsAutocheckoutEnabled()? 0 : kRequiredFillableFields; |
| 559 } |
| 560 |
| 554 bool FormStructure::IsAutofillable(bool require_method_post) const { | 561 bool FormStructure::IsAutofillable(bool require_method_post) const { |
| 555 // TODO(ramankk): Remove this check once we have better way of identifying the | 562 if (autofill_count() < RequiredFillableFields()) |
| 556 // cases to trigger experimental form filling. | |
| 557 if (experimental_form_filling_enabled_) | |
| 558 return true; | |
| 559 | |
| 560 if (autofill_count() < kRequiredFillableFields) | |
| 561 return false; | 563 return false; |
| 562 | 564 |
| 563 return ShouldBeParsed(require_method_post); | 565 return ShouldBeParsed(require_method_post); |
| 564 } | 566 } |
| 565 | 567 |
| 566 void FormStructure::UpdateAutofillCount() { | 568 void FormStructure::UpdateAutofillCount() { |
| 567 autofill_count_ = 0; | 569 autofill_count_ = 0; |
| 568 for (std::vector<AutofillField*>::const_iterator iter = begin(); | 570 for (std::vector<AutofillField*>::const_iterator iter = begin(); |
| 569 iter != end(); ++iter) { | 571 iter != end(); ++iter) { |
| 570 AutofillField* field = *iter; | 572 AutofillField* field = *iter; |
| 571 if (field && field->IsFieldFillable()) | 573 if (field && field->IsFieldFillable()) |
| 572 ++autofill_count_; | 574 ++autofill_count_; |
| 573 } | 575 } |
| 574 } | 576 } |
| 575 | 577 |
| 576 bool FormStructure::ShouldBeParsed(bool require_method_post) const { | 578 bool FormStructure::ShouldBeParsed(bool require_method_post) const { |
| 577 // TODO(ramankk): Remove this check once we have better way of identifying the | |
| 578 // cases to trigger experimental form filling. | |
| 579 if (experimental_form_filling_enabled_) | |
| 580 return true; | |
| 581 | |
| 582 // Ignore counting checkable elements towards minimum number of elements | 579 // Ignore counting checkable elements towards minimum number of elements |
| 583 // required to parse. This avoids trying to crowdsource forms with few text | 580 // required to parse. This avoids trying to crowdsource forms with few text |
| 584 // or select elements. | 581 // or select elements. |
| 585 if ((field_count() - checkable_field_count()) < kRequiredFillableFields) | 582 if ((field_count() - checkable_field_count()) < RequiredFillableFields()) |
| 586 return false; | 583 return false; |
| 587 | 584 |
| 588 // Rule out http(s)://*/search?... | 585 // Rule out http(s)://*/search?... |
| 589 // e.g. http://www.google.com/search?q=... | 586 // e.g. http://www.google.com/search?q=... |
| 590 // http://search.yahoo.com/search?p=... | 587 // http://search.yahoo.com/search?p=... |
| 591 if (target_url_.path() == "/search") | 588 if (target_url_.path() == "/search") |
| 592 return false; | 589 return false; |
| 593 | 590 |
| 594 // Make sure there as at least one text field. | 591 // Make sure there as at least one text field. |
| 595 bool has_text_field = false; | 592 bool has_text_field = false; |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 773 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH, | 770 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH, |
| 774 experiment_id); | 771 experiment_id); |
| 775 } else { | 772 } else { |
| 776 metric_logger.LogQualityMetric( | 773 metric_logger.LogQualityMetric( |
| 777 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH, | 774 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH, |
| 778 experiment_id); | 775 experiment_id); |
| 779 } | 776 } |
| 780 } | 777 } |
| 781 } | 778 } |
| 782 | 779 |
| 783 if (num_detected_field_types < kRequiredFillableFields) { | 780 if (num_detected_field_types < RequiredFillableFields()) { |
| 784 metric_logger.LogUserHappinessMetric( | 781 metric_logger.LogUserHappinessMetric( |
| 785 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM); | 782 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM); |
| 786 } else { | 783 } else { |
| 787 if (did_autofill_all_possible_fields) { | 784 if (did_autofill_all_possible_fields) { |
| 788 metric_logger.LogUserHappinessMetric( | 785 metric_logger.LogUserHappinessMetric( |
| 789 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL); | 786 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL); |
| 790 } else if (did_autofill_some_possible_fields) { | 787 } else if (did_autofill_some_possible_fields) { |
| 791 metric_logger.LogUserHappinessMetric( | 788 metric_logger.LogUserHappinessMetric( |
| 792 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME); | 789 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME); |
| 793 } else { | 790 } else { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 930 buzz::XmlElement *field_element = new buzz::XmlElement( | 927 buzz::XmlElement *field_element = new buzz::XmlElement( |
| 931 buzz::QName(kXMLElementField)); | 928 buzz::QName(kXMLElementField)); |
| 932 | 929 |
| 933 field_element->SetAttr(buzz::QName(kAttributeSignature), | 930 field_element->SetAttr(buzz::QName(kAttributeSignature), |
| 934 field->FieldSignature()); | 931 field->FieldSignature()); |
| 935 field_element->SetAttr(buzz::QName(kAttributeAutofillType), | 932 field_element->SetAttr(buzz::QName(kAttributeAutofillType), |
| 936 base::IntToString(*field_type)); | 933 base::IntToString(*field_type)); |
| 937 encompassing_xml_element->AddElement(field_element); | 934 encompassing_xml_element->AddElement(field_element); |
| 938 } | 935 } |
| 939 } else { | 936 } else { |
| 940 // Skip putting checkable fields in the request if the flag is not set. | 937 // Skip putting checkable fields in the request if autocheckout is not |
| 941 if (field->is_checkable && !experimental_form_filling_enabled_) | 938 // enabled. |
| 939 if (field->is_checkable && !IsAutocheckoutEnabled()) |
| 942 continue; | 940 continue; |
| 943 | 941 |
| 944 buzz::XmlElement *field_element = new buzz::XmlElement( | 942 buzz::XmlElement *field_element = new buzz::XmlElement( |
| 945 buzz::QName(kXMLElementField)); | 943 buzz::QName(kXMLElementField)); |
| 946 field_element->SetAttr(buzz::QName(kAttributeSignature), | 944 field_element->SetAttr(buzz::QName(kAttributeSignature), |
| 947 field->FieldSignature()); | 945 field->FieldSignature()); |
| 948 encompassing_xml_element->AddElement(field_element); | 946 encompassing_xml_element->AddElement(field_element); |
| 949 } | 947 } |
| 950 } | 948 } |
| 951 return true; | 949 return true; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1114 for (std::vector<AutofillField*>::iterator field = fields_.begin(); | 1112 for (std::vector<AutofillField*>::iterator field = fields_.begin(); |
| 1115 field != fields_.end(); ++field) { | 1113 field != fields_.end(); ++field) { |
| 1116 AutofillType::FieldTypeGroup field_type_group = | 1114 AutofillType::FieldTypeGroup field_type_group = |
| 1117 AutofillType((*field)->type()).group(); | 1115 AutofillType((*field)->type()).group(); |
| 1118 if (field_type_group == AutofillType::CREDIT_CARD) | 1116 if (field_type_group == AutofillType::CREDIT_CARD) |
| 1119 (*field)->set_section((*field)->section() + "-cc"); | 1117 (*field)->set_section((*field)->section() + "-cc"); |
| 1120 else | 1118 else |
| 1121 (*field)->set_section((*field)->section() + "-default"); | 1119 (*field)->set_section((*field)->section() + "-default"); |
| 1122 } | 1120 } |
| 1123 } | 1121 } |
| OLD | NEW |