Chromium Code Reviews| 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 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 228 target_url_(form.action), | 228 target_url_(form.action), |
| 229 autofill_count_(0), | 229 autofill_count_(0), |
| 230 upload_required_(USE_UPLOAD_RATES), | 230 upload_required_(USE_UPLOAD_RATES), |
| 231 server_experiment_id_("no server response"), | 231 server_experiment_id_("no server response"), |
| 232 has_author_specified_types_(false) { | 232 has_author_specified_types_(false) { |
| 233 // Copy the form fields. | 233 // Copy the form fields. |
| 234 std::map<string16, size_t> unique_names; | 234 std::map<string16, size_t> unique_names; |
| 235 for (std::vector<FormFieldData>::const_iterator field = | 235 for (std::vector<FormFieldData>::const_iterator field = |
| 236 form.fields.begin(); | 236 form.fields.begin(); |
| 237 field != form.fields.end(); field++) { | 237 field != form.fields.end(); field++) { |
| 238 // Add all supported form fields (including with empty names) to the | 238 // Skipping checkable elements when flag is not set, else these fields will |
| 239 // signature. This is a requirement for Autofill servers. | 239 // interfere with existing field signatures with Autofill servers. |
| 240 form_signature_field_names_.append("&"); | 240 // TODO(ramankk): Add checkable elements only on whitelisted pages |
| 241 form_signature_field_names_.append(UTF16ToUTF8(field->name)); | 241 if (!field->is_checkable || |
| 242 CommandLine::ForCurrentProcess()->HasSwitch( | |
| 243 switches::kEnableExperimentalFormFilling)) { | |
| 244 // Add all supported form fields (including with empty names) to the | |
| 245 // signature. This is a requirement for Autofill servers. | |
| 246 form_signature_field_names_.append("&"); | |
| 247 form_signature_field_names_.append(UTF16ToUTF8(field->name)); | |
| 248 } | |
| 242 | 249 |
| 243 // Generate a unique name for this field by appending a counter to the name. | 250 // Generate a unique name for this field by appending a counter to the name. |
| 244 // Make sure to prepend the counter with a non-numeric digit so that we are | 251 // Make sure to prepend the counter with a non-numeric digit so that we are |
| 245 // guaranteed to avoid collisions. | 252 // guaranteed to avoid collisions. |
| 246 if (!unique_names.count(field->name)) | 253 if (!unique_names.count(field->name)) |
| 247 unique_names[field->name] = 1; | 254 unique_names[field->name] = 1; |
| 248 else | 255 else |
| 249 ++unique_names[field->name]; | 256 ++unique_names[field->name]; |
| 250 string16 unique_name = field->name + ASCIIToUTF16("_") + | 257 string16 unique_name = field->name + ASCIIToUTF16("_") + |
| 251 base::IntToString16(unique_names[field->name]); | 258 base::IntToString16(unique_names[field->name]); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 return true; | 406 return true; |
| 400 } | 407 } |
| 401 | 408 |
| 402 // static | 409 // static |
| 403 void FormStructure::ParseQueryResponse(const std::string& response_xml, | 410 void FormStructure::ParseQueryResponse(const std::string& response_xml, |
| 404 const std::vector<FormStructure*>& forms, | 411 const std::vector<FormStructure*>& forms, |
| 405 const AutofillMetrics& metric_logger) { | 412 const AutofillMetrics& metric_logger) { |
| 406 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_RECEIVED); | 413 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_RECEIVED); |
| 407 | 414 |
| 408 // Parse the field types from the server response to the query. | 415 // Parse the field types from the server response to the query. |
| 409 std::vector<AutofillFieldType> field_types; | 416 std::vector<AutofillServerFieldInfo> field_infos; |
| 410 UploadRequired upload_required; | 417 UploadRequired upload_required; |
| 411 std::string experiment_id; | 418 std::string experiment_id; |
| 412 AutofillQueryXmlParser parse_handler(&field_types, &upload_required, | 419 AutofillQueryXmlParser parse_handler(&field_infos, &upload_required, |
| 413 &experiment_id); | 420 &experiment_id); |
| 414 buzz::XmlParser parser(&parse_handler); | 421 buzz::XmlParser parser(&parse_handler); |
| 415 parser.Parse(response_xml.c_str(), response_xml.length(), true); | 422 parser.Parse(response_xml.c_str(), response_xml.length(), true); |
| 416 if (!parse_handler.succeeded()) | 423 if (!parse_handler.succeeded()) |
| 417 return; | 424 return; |
| 418 | 425 |
| 419 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED); | 426 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED); |
| 420 metric_logger.LogServerExperimentIdForQuery(experiment_id); | 427 metric_logger.LogServerExperimentIdForQuery(experiment_id); |
| 421 | 428 |
| 422 bool heuristics_detected_fillable_field = false; | 429 bool heuristics_detected_fillable_field = false; |
| 423 bool query_response_overrode_heuristics = false; | 430 bool query_response_overrode_heuristics = false; |
| 424 | 431 |
| 425 // Copy the field types into the actual form. | 432 // Copy the field types into the actual form. |
| 426 std::vector<AutofillFieldType>::iterator current_type = field_types.begin(); | 433 std::vector<AutofillServerFieldInfo>::iterator current_info = |
| 434 field_infos.begin(); | |
| 427 for (std::vector<FormStructure*>::const_iterator iter = forms.begin(); | 435 for (std::vector<FormStructure*>::const_iterator iter = forms.begin(); |
| 428 iter != forms.end(); ++iter) { | 436 iter != forms.end(); ++iter) { |
| 429 FormStructure* form = *iter; | 437 FormStructure* form = *iter; |
| 430 form->upload_required_ = upload_required; | 438 form->upload_required_ = upload_required; |
| 431 form->server_experiment_id_ = experiment_id; | 439 form->server_experiment_id_ = experiment_id; |
| 432 | 440 |
| 433 for (std::vector<AutofillField*>::iterator field = form->fields_.begin(); | 441 for (std::vector<AutofillField*>::iterator field = form->fields_.begin(); |
| 434 field != form->fields_.end(); ++field, ++current_type) { | 442 field != form->fields_.end(); ++field, ++current_info) { |
| 435 // In some cases *successful* response does not return all the fields. | 443 // In some cases *successful* response does not return all the fields. |
| 436 // Quit the update of the types then. | 444 // Quit the update of the types then. |
| 437 if (current_type == field_types.end()) | 445 if (current_info == field_infos.end()) |
| 438 break; | 446 break; |
| 439 | 447 |
| 440 // UNKNOWN_TYPE is reserved for use by the client. | 448 // UNKNOWN_TYPE is reserved for use by the client. |
| 441 DCHECK_NE(*current_type, UNKNOWN_TYPE); | 449 DCHECK_NE(current_info->field_type, UNKNOWN_TYPE); |
| 442 | 450 |
| 443 AutofillFieldType heuristic_type = (*field)->type(); | 451 AutofillFieldType heuristic_type = (*field)->type(); |
| 444 if (heuristic_type != UNKNOWN_TYPE) | 452 if (heuristic_type != UNKNOWN_TYPE) |
| 445 heuristics_detected_fillable_field = true; | 453 heuristics_detected_fillable_field = true; |
| 446 | 454 |
| 447 (*field)->set_server_type(*current_type); | 455 (*field)->set_server_type(current_info->field_type); |
| 448 if (heuristic_type != (*field)->type()) | 456 if (heuristic_type != (*field)->type()) |
| 449 query_response_overrode_heuristics = true; | 457 query_response_overrode_heuristics = true; |
| 458 | |
| 459 // Copy default value into the field if available. | |
| 460 if (!current_info->default_value.empty()) | |
| 461 (*field)->set_default_value(current_info->default_value); | |
| 450 } | 462 } |
| 451 | 463 |
| 452 form->UpdateAutofillCount(); | 464 form->UpdateAutofillCount(); |
| 453 form->IdentifySections(false); | 465 form->IdentifySections(false); |
| 454 } | 466 } |
| 455 | 467 |
| 456 AutofillMetrics::ServerQueryMetric metric; | 468 AutofillMetrics::ServerQueryMetric metric; |
| 457 if (query_response_overrode_heuristics) { | 469 if (query_response_overrode_heuristics) { |
| 458 if (heuristics_detected_fillable_field) { | 470 if (heuristics_detected_fillable_field) { |
| 459 metric = AutofillMetrics::QUERY_RESPONSE_OVERRODE_LOCAL_HEURISTICS; | 471 metric = AutofillMetrics::QUERY_RESPONSE_OVERRODE_LOCAL_HEURISTICS; |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 566 it != end() && !has_text_field; ++it) { | 578 it != end() && !has_text_field; ++it) { |
| 567 has_text_field |= (*it)->form_control_type != "select-one"; | 579 has_text_field |= (*it)->form_control_type != "select-one"; |
| 568 } | 580 } |
| 569 if (!has_text_field) | 581 if (!has_text_field) |
| 570 return false; | 582 return false; |
| 571 | 583 |
| 572 return !require_method_post || (method_ == POST); | 584 return !require_method_post || (method_ == POST); |
| 573 } | 585 } |
| 574 | 586 |
| 575 bool FormStructure::ShouldBeCrowdsourced() const { | 587 bool FormStructure::ShouldBeCrowdsourced() const { |
| 576 return !has_author_specified_types_ && ShouldBeParsed(true); | 588 return !has_author_specified_types_ && ShouldBeParsed(true); |
|
Ilya Sherman
2012/12/15 01:08:36
The test expectations changes made me realize that
Raman Kakilate
2012/12/17 20:11:01
Thanks for catching this.
Done.
| |
| 577 } | 589 } |
| 578 | 590 |
| 579 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { | 591 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { |
| 580 // Map from field signatures to cached fields. | 592 // Map from field signatures to cached fields. |
| 581 std::map<std::string, const AutofillField*> cached_fields; | 593 std::map<std::string, const AutofillField*> cached_fields; |
| 582 for (size_t i = 0; i < cached_form.field_count(); ++i) { | 594 for (size_t i = 0; i < cached_form.field_count(); ++i) { |
| 583 const AutofillField* field = cached_form.field(i); | 595 const AutofillField* field = cached_form.field(i); |
| 584 cached_fields[field->FieldSignature()] = field; | 596 cached_fields[field->FieldSignature()] = field; |
| 585 } | 597 } |
| 586 | 598 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 877 // Do not send requests for forms with more than this many fields, as they are | 889 // Do not send requests for forms with more than this many fields, as they are |
| 878 // near certainly not valid/auto-fillable. | 890 // near certainly not valid/auto-fillable. |
| 879 const size_t kMaxFieldsOnTheForm = 48; | 891 const size_t kMaxFieldsOnTheForm = 48; |
| 880 if (field_count() > kMaxFieldsOnTheForm) | 892 if (field_count() > kMaxFieldsOnTheForm) |
| 881 return false; | 893 return false; |
| 882 | 894 |
| 883 // Add the child nodes for the form fields. | 895 // Add the child nodes for the form fields. |
| 884 for (size_t index = 0; index < field_count(); ++index) { | 896 for (size_t index = 0; index < field_count(); ++index) { |
| 885 const AutofillField* field = fields_[index]; | 897 const AutofillField* field = fields_[index]; |
| 886 if (request_type == FormStructure::UPLOAD) { | 898 if (request_type == FormStructure::UPLOAD) { |
| 899 // Don't upload checkable fields. | |
| 900 if (field->is_checkable) | |
| 901 continue; | |
| 902 | |
| 887 FieldTypeSet types = field->possible_types(); | 903 FieldTypeSet types = field->possible_types(); |
| 888 // |types| could be empty in unit-tests only. | 904 // |types| could be empty in unit-tests only. |
| 889 for (FieldTypeSet::iterator field_type = types.begin(); | 905 for (FieldTypeSet::iterator field_type = types.begin(); |
| 890 field_type != types.end(); ++field_type) { | 906 field_type != types.end(); ++field_type) { |
| 891 buzz::XmlElement *field_element = new buzz::XmlElement( | 907 buzz::XmlElement *field_element = new buzz::XmlElement( |
| 892 buzz::QName(kXMLElementField)); | 908 buzz::QName(kXMLElementField)); |
| 893 | 909 |
| 894 field_element->SetAttr(buzz::QName(kAttributeSignature), | 910 field_element->SetAttr(buzz::QName(kAttributeSignature), |
| 895 field->FieldSignature()); | 911 field->FieldSignature()); |
| 896 field_element->SetAttr(buzz::QName(kAttributeAutofillType), | 912 field_element->SetAttr(buzz::QName(kAttributeAutofillType), |
| 897 base::IntToString(*field_type)); | 913 base::IntToString(*field_type)); |
| 898 encompassing_xml_element->AddElement(field_element); | 914 encompassing_xml_element->AddElement(field_element); |
| 899 } | 915 } |
| 900 } else { | 916 } else { |
| 917 // Skip putting checkable fields in the request if the flag is not set. | |
| 918 if (field->is_checkable && | |
| 919 !CommandLine::ForCurrentProcess()->HasSwitch( | |
| 920 switches::kEnableExperimentalFormFilling)) | |
| 921 continue; | |
| 922 | |
| 901 buzz::XmlElement *field_element = new buzz::XmlElement( | 923 buzz::XmlElement *field_element = new buzz::XmlElement( |
| 902 buzz::QName(kXMLElementField)); | 924 buzz::QName(kXMLElementField)); |
| 903 field_element->SetAttr(buzz::QName(kAttributeSignature), | 925 field_element->SetAttr(buzz::QName(kAttributeSignature), |
| 904 field->FieldSignature()); | 926 field->FieldSignature()); |
| 905 encompassing_xml_element->AddElement(field_element); | 927 encompassing_xml_element->AddElement(field_element); |
| 906 } | 928 } |
| 907 } | 929 } |
| 908 return true; | 930 return true; |
| 909 } | 931 } |
| 910 | 932 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1071 for (std::vector<AutofillField*>::iterator field = fields_.begin(); | 1093 for (std::vector<AutofillField*>::iterator field = fields_.begin(); |
| 1072 field != fields_.end(); ++field) { | 1094 field != fields_.end(); ++field) { |
| 1073 AutofillType::FieldTypeGroup field_type_group = | 1095 AutofillType::FieldTypeGroup field_type_group = |
| 1074 AutofillType((*field)->type()).group(); | 1096 AutofillType((*field)->type()).group(); |
| 1075 if (field_type_group == AutofillType::CREDIT_CARD) | 1097 if (field_type_group == AutofillType::CREDIT_CARD) |
| 1076 (*field)->set_section((*field)->section() + "-cc"); | 1098 (*field)->set_section((*field)->section() + "-cc"); |
| 1077 else | 1099 else |
| 1078 (*field)->set_section((*field)->section() + "-default"); | 1100 (*field)->set_section((*field)->section() + "-default"); |
| 1079 } | 1101 } |
| 1080 } | 1102 } |
| OLD | NEW |