OLD | NEW |
---|---|
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" |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
345 | 345 |
346 } // namespace | 346 } // namespace |
347 | 347 |
348 FormStructure::FormStructure(const FormData& form) | 348 FormStructure::FormStructure(const FormData& form) |
349 : form_name_(form.name), | 349 : form_name_(form.name), |
350 source_url_(form.origin), | 350 source_url_(form.origin), |
351 target_url_(form.action), | 351 target_url_(form.action), |
352 autofill_count_(0), | 352 autofill_count_(0), |
353 active_field_count_(0), | 353 active_field_count_(0), |
354 upload_required_(USE_UPLOAD_RATES), | 354 upload_required_(USE_UPLOAD_RATES), |
355 has_author_specified_types_(false) { | 355 has_author_specified_types_(false), |
356 has_password_field_(false) { | |
356 // Copy the form fields. | 357 // Copy the form fields. |
357 std::map<base::string16, size_t> unique_names; | 358 std::map<base::string16, size_t> unique_names; |
358 for (std::vector<FormFieldData>::const_iterator field = | 359 for (std::vector<FormFieldData>::const_iterator field = |
359 form.fields.begin(); | 360 form.fields.begin(); |
360 field != form.fields.end(); ++field) { | 361 field != form.fields.end(); ++field) { |
361 if (!ShouldSkipField(*field)) { | 362 if (!ShouldSkipField(*field)) { |
362 // Add all supported form fields (including with empty names) to the | 363 // Add all supported form fields (including with empty names) to the |
363 // signature. This is a requirement for Autofill servers. | 364 // signature. This is a requirement for Autofill servers. |
364 form_signature_field_names_.append("&"); | 365 form_signature_field_names_.append("&"); |
365 form_signature_field_names_.append(StripDigitsIfRequired(field->name)); | 366 form_signature_field_names_.append(StripDigitsIfRequired(field->name)); |
366 | 367 |
367 ++active_field_count_; | 368 ++active_field_count_; |
368 } | 369 } |
369 | 370 |
371 if (field->form_control_type == "password") | |
372 has_password_field_ = true; | |
373 | |
370 // Generate a unique name for this field by appending a counter to the name. | 374 // Generate a unique name for this field by appending a counter to the name. |
371 // Make sure to prepend the counter with a non-numeric digit so that we are | 375 // Make sure to prepend the counter with a non-numeric digit so that we are |
372 // guaranteed to avoid collisions. | 376 // guaranteed to avoid collisions. |
373 if (!unique_names.count(field->name)) | 377 if (!unique_names.count(field->name)) |
374 unique_names[field->name] = 1; | 378 unique_names[field->name] = 1; |
375 else | 379 else |
376 ++unique_names[field->name]; | 380 ++unique_names[field->name]; |
377 base::string16 unique_name = field->name + base::ASCIIToUTF16("_") + | 381 base::string16 unique_name = field->name + base::ASCIIToUTF16("_") + |
378 base::IntToString16(unique_names[field->name]); | 382 base::IntToString16(unique_names[field->name]); |
379 fields_.push_back(new AutofillField(*field, unique_name)); | 383 fields_.push_back(new AutofillField(*field, unique_name)); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
553 &upload_required); | 557 &upload_required); |
554 buzz::XmlParser parser(&parse_handler); | 558 buzz::XmlParser parser(&parse_handler); |
555 parser.Parse(response_xml.c_str(), response_xml.length(), true); | 559 parser.Parse(response_xml.c_str(), response_xml.length(), true); |
556 if (!parse_handler.succeeded()) | 560 if (!parse_handler.succeeded()) |
557 return; | 561 return; |
558 | 562 |
559 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED); | 563 metric_logger.LogServerQueryMetric(AutofillMetrics::QUERY_RESPONSE_PARSED); |
560 | 564 |
561 bool heuristics_detected_fillable_field = false; | 565 bool heuristics_detected_fillable_field = false; |
562 bool query_response_overrode_heuristics = false; | 566 bool query_response_overrode_heuristics = false; |
567 bool non_password_field_processed = false; | |
563 | 568 |
564 // Copy the field types into the actual form. | 569 // Copy the field types into the actual form. |
565 std::vector<AutofillServerFieldInfo>::iterator current_info = | 570 std::vector<AutofillServerFieldInfo>::iterator current_info = |
566 field_infos.begin(); | 571 field_infos.begin(); |
567 for (std::vector<FormStructure*>::const_iterator iter = forms.begin(); | 572 for (std::vector<FormStructure*>::const_iterator iter = forms.begin(); |
568 iter != forms.end(); ++iter) { | 573 iter != forms.end(); ++iter) { |
569 FormStructure* form = *iter; | 574 FormStructure* form = *iter; |
570 form->upload_required_ = upload_required; | 575 form->upload_required_ = upload_required; |
571 | 576 |
572 for (std::vector<AutofillField*>::iterator field = form->fields_.begin(); | 577 for (std::vector<AutofillField*>::iterator field = form->fields_.begin(); |
573 field != form->fields_.end(); ++field) { | 578 field != form->fields_.end(); ++field) { |
574 if (form->ShouldSkipField(**field)) | 579 if (form->ShouldSkipField(**field)) |
575 continue; | 580 continue; |
576 | 581 |
577 // In some cases *successful* response does not return all the fields. | 582 // In some cases *successful* response does not return all the fields. |
578 // Quit the update of the types then. | 583 // Quit the update of the types then. |
579 if (current_info == field_infos.end()) | 584 if (current_info == field_infos.end()) |
580 break; | 585 break; |
581 | 586 |
582 // UNKNOWN_TYPE is reserved for use by the client. | 587 if (form->ShouldSkipProcessingNonPasswordFields()) { |
583 DCHECK_NE(current_info->field_type, UNKNOWN_TYPE); | 588 // Heuristic values can be ignored for password fields as Autofill |
589 // doesn't handle them. UMA stats can also be skipped in that case. | |
590 if ((*field)->Type().group() == PASSWORD_FIELD) | |
591 (*field)->set_server_type(current_info->field_type); | |
592 } else { | |
593 non_password_field_processed = true; | |
Ilya Sherman
2014/10/24 01:24:45
Wait, where do you check that a non-password field
Garrett Casto
2014/10/24 21:13:09
I agree that the name doesn't do a great job of ex
| |
584 | 594 |
585 ServerFieldType heuristic_type = (*field)->heuristic_type(); | 595 // UNKNOWN_TYPE is reserved for use by the client. |
586 if (heuristic_type != UNKNOWN_TYPE) | 596 DCHECK_NE(current_info->field_type, UNKNOWN_TYPE); |
587 heuristics_detected_fillable_field = true; | |
588 | 597 |
589 (*field)->set_server_type(current_info->field_type); | 598 ServerFieldType heuristic_type = (*field)->heuristic_type(); |
590 if (heuristic_type != (*field)->Type().GetStorableType()) | 599 if (heuristic_type != UNKNOWN_TYPE) |
591 query_response_overrode_heuristics = true; | 600 heuristics_detected_fillable_field = true; |
592 | 601 |
593 // Copy default value into the field if available. | 602 (*field)->set_server_type(current_info->field_type); |
594 if (!current_info->default_value.empty()) | 603 if (heuristic_type != (*field)->Type().GetStorableType()) |
595 (*field)->set_default_value(current_info->default_value); | 604 query_response_overrode_heuristics = true; |
605 | |
606 // Copy default value into the field if available. | |
607 if (!current_info->default_value.empty()) | |
608 (*field)->set_default_value(current_info->default_value); | |
609 } | |
596 | 610 |
597 ++current_info; | 611 ++current_info; |
598 } | 612 } |
599 | 613 |
600 form->UpdateAutofillCount(); | 614 form->UpdateAutofillCount(); |
601 form->IdentifySections(false); | 615 form->IdentifySections(false); |
602 } | 616 } |
603 | 617 |
604 AutofillMetrics::ServerQueryMetric metric; | 618 // Only log metrics if response was for non-password fields, since password |
605 if (query_response_overrode_heuristics) { | 619 // fields don't have local heuristics to measure. |
606 if (heuristics_detected_fillable_field) { | 620 if (non_password_field_processed) { |
607 metric = AutofillMetrics::QUERY_RESPONSE_OVERRODE_LOCAL_HEURISTICS; | 621 AutofillMetrics::ServerQueryMetric metric; |
622 if (query_response_overrode_heuristics) { | |
623 if (heuristics_detected_fillable_field) { | |
624 metric = AutofillMetrics::QUERY_RESPONSE_OVERRODE_LOCAL_HEURISTICS; | |
625 } else { | |
626 metric = AutofillMetrics::QUERY_RESPONSE_WITH_NO_LOCAL_HEURISTICS; | |
627 } | |
608 } else { | 628 } else { |
609 metric = AutofillMetrics::QUERY_RESPONSE_WITH_NO_LOCAL_HEURISTICS; | 629 metric = AutofillMetrics::QUERY_RESPONSE_MATCHED_LOCAL_HEURISTICS; |
610 } | 630 } |
611 } else { | 631 metric_logger.LogServerQueryMetric(metric); |
612 metric = AutofillMetrics::QUERY_RESPONSE_MATCHED_LOCAL_HEURISTICS; | |
613 } | 632 } |
614 metric_logger.LogServerQueryMetric(metric); | |
615 } | 633 } |
616 | 634 |
617 // static | 635 // static |
618 void FormStructure::GetFieldTypePredictions( | 636 void FormStructure::GetFieldTypePredictions( |
619 const std::vector<FormStructure*>& form_structures, | 637 const std::vector<FormStructure*>& form_structures, |
620 std::vector<FormDataPredictions>* forms) { | 638 std::vector<FormDataPredictions>* forms) { |
621 forms->clear(); | 639 forms->clear(); |
622 forms->reserve(form_structures.size()); | 640 forms->reserve(form_structures.size()); |
623 for (size_t i = 0; i < form_structures.size(); ++i) { | 641 for (size_t i = 0; i < form_structures.size(); ++i) { |
624 FormStructure* form_structure = form_structures[i]; | 642 FormStructure* form_structure = form_structures[i]; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
699 bool has_text_field = false; | 717 bool has_text_field = false; |
700 for (std::vector<AutofillField*>::const_iterator it = begin(); | 718 for (std::vector<AutofillField*>::const_iterator it = begin(); |
701 it != end() && !has_text_field; ++it) { | 719 it != end() && !has_text_field; ++it) { |
702 has_text_field |= (*it)->form_control_type != "select-one"; | 720 has_text_field |= (*it)->form_control_type != "select-one"; |
703 } | 721 } |
704 | 722 |
705 return has_text_field; | 723 return has_text_field; |
706 } | 724 } |
707 | 725 |
708 bool FormStructure::ShouldBeCrowdsourced() const { | 726 bool FormStructure::ShouldBeCrowdsourced() const { |
709 return !has_author_specified_types_ && ShouldBeParsed(); | 727 return (has_password_field_ || !has_author_specified_types_) && |
728 ShouldBeParsed(); | |
729 } | |
730 | |
731 bool FormStructure::ShouldSkipProcessingNonPasswordFields() const { | |
Ilya Sherman
2014/10/24 01:24:45
This method name is pretty long and, IMO, still a
Garrett Casto
2014/10/24 21:13:09
Done.
| |
732 return has_password_field_ && has_author_specified_types_; | |
710 } | 733 } |
711 | 734 |
712 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { | 735 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { |
713 // Map from field signatures to cached fields. | 736 // Map from field signatures to cached fields. |
714 std::map<std::string, const AutofillField*> cached_fields; | 737 std::map<std::string, const AutofillField*> cached_fields; |
715 for (size_t i = 0; i < cached_form.field_count(); ++i) { | 738 for (size_t i = 0; i < cached_form.field_count(); ++i) { |
716 const AutofillField* field = cached_form.field(i); | 739 const AutofillField* field = cached_form.field(i); |
717 cached_fields[field->FieldSignature()] = field; | 740 cached_fields[field->FieldSignature()] = field; |
718 } | 741 } |
719 | 742 |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1228 field != fields_.end(); ++field) { | 1251 field != fields_.end(); ++field) { |
1229 FieldTypeGroup field_type_group = (*field)->Type().group(); | 1252 FieldTypeGroup field_type_group = (*field)->Type().group(); |
1230 if (field_type_group == CREDIT_CARD) | 1253 if (field_type_group == CREDIT_CARD) |
1231 (*field)->set_section((*field)->section() + "-cc"); | 1254 (*field)->set_section((*field)->section() + "-cc"); |
1232 else | 1255 else |
1233 (*field)->set_section((*field)->section() + "-default"); | 1256 (*field)->set_section((*field)->section() + "-default"); |
1234 } | 1257 } |
1235 } | 1258 } |
1236 | 1259 |
1237 } // namespace autofill | 1260 } // namespace autofill |
OLD | NEW |