| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 686 const base::TimeTicks& submission_time, | 686 const base::TimeTicks& submission_time, |
| 687 rappor::RapporServiceImpl* rappor_service, | 687 rappor::RapporServiceImpl* rappor_service, |
| 688 bool did_show_suggestions, | 688 bool did_show_suggestions, |
| 689 bool observed_submission) const { | 689 bool observed_submission) const { |
| 690 size_t num_detected_field_types = 0; | 690 size_t num_detected_field_types = 0; |
| 691 size_t num_server_mismatches = 0; | 691 size_t num_server_mismatches = 0; |
| 692 size_t num_heuristic_mismatches = 0; | 692 size_t num_heuristic_mismatches = 0; |
| 693 size_t num_edited_autofilled_fields = 0; | 693 size_t num_edited_autofilled_fields = 0; |
| 694 bool did_autofill_all_possible_fields = true; | 694 bool did_autofill_all_possible_fields = true; |
| 695 bool did_autofill_some_possible_fields = false; | 695 bool did_autofill_some_possible_fields = false; |
| 696 |
| 697 // Determine the correct suffix for the metric, depending on whether or |
| 698 // not a submission was observed. |
| 699 const AutofillMetrics::QualityMetricType metric_type = |
| 700 observed_submission ? AutofillMetrics::TYPE_SUBMISSION |
| 701 : AutofillMetrics::TYPE_NO_SUBMISSION; |
| 702 |
| 696 for (size_t i = 0; i < field_count(); ++i) { | 703 for (size_t i = 0; i < field_count(); ++i) { |
| 697 auto* const field = this->field(i); | 704 auto* const field = this->field(i); |
| 698 | 705 |
| 699 // No further logging for password fields. Those are primarily related to a | 706 // No further logging for password fields. Those are primarily related to a |
| 700 // different feature code path, and so make more sense to track outside of | 707 // different feature code path, and so make more sense to track outside of |
| 701 // this metric. | 708 // this metric. |
| 702 if (field->form_control_type == "password") | 709 if (field->form_control_type == "password") |
| 703 continue; | 710 continue; |
| 704 | 711 |
| 705 // We count fields that were autofilled but later modified, regardless of | 712 // We count fields that were autofilled but later modified, regardless of |
| 706 // whether the data now in the field is recognized. | 713 // whether the data now in the field is recognized. |
| 707 if (field->previously_autofilled()) | 714 if (field->previously_autofilled()) |
| 708 num_edited_autofilled_fields++; | 715 num_edited_autofilled_fields++; |
| 709 | 716 |
| 710 // No further logging for empty fields nor for fields where the entered data | 717 // Aliases for the field types predicted by heuristics, server and overall. |
| 711 // does not appear to already exist in the user's stored Autofill data. | 718 ServerFieldType heuristic_type = |
| 719 AutofillType(field->heuristic_type()).GetStorableType(); |
| 720 ServerFieldType server_type = |
| 721 AutofillType(field->server_type()).GetStorableType(); |
| 722 ServerFieldType predicted_type = field->Type().GetStorableType(); |
| 723 |
| 712 const ServerFieldTypeSet& field_types = field->possible_types(); | 724 const ServerFieldTypeSet& field_types = field->possible_types(); |
| 713 DCHECK(!field_types.empty()); | 725 DCHECK(!field_types.empty()); |
| 714 if (field_types.count(EMPTY_TYPE) || field_types.count(UNKNOWN_TYPE)) | 726 |
| 727 // If the field data is empty, or unrecognized, log whether or not autofill |
| 728 // predicted that it would be populated with an autofillable data type. |
| 729 bool has_empty_data = field_types.count(EMPTY_TYPE) != 0; |
| 730 bool has_unrecognized_data = field_types.count(UNKNOWN_TYPE) != 0; |
| 731 if (has_empty_data || has_unrecognized_data) { |
| 732 AutofillMetrics::FieldTypeQualityMetric match_empty_or_unknown = |
| 733 has_empty_data ? AutofillMetrics::TYPE_MATCH_EMPTY |
| 734 : AutofillMetrics::TYPE_MATCH_UNKNOWN; |
| 735 AutofillMetrics::FieldTypeQualityMetric mismatch_empty_or_unknown = |
| 736 has_empty_data ? AutofillMetrics::TYPE_MISMATCH_EMPTY |
| 737 : AutofillMetrics::TYPE_MISMATCH_UNKNOWN; |
| 738 ServerFieldType field_type = has_empty_data ? EMPTY_TYPE : UNKNOWN_TYPE; |
| 739 AutofillMetrics::LogHeuristicTypePrediction( |
| 740 (heuristic_type == UNKNOWN_TYPE ? match_empty_or_unknown |
| 741 : mismatch_empty_or_unknown), |
| 742 field_type, metric_type); |
| 743 AutofillMetrics::LogServerTypePrediction( |
| 744 (server_type == NO_SERVER_DATA ? match_empty_or_unknown |
| 745 : mismatch_empty_or_unknown), |
| 746 field_type, metric_type); |
| 747 AutofillMetrics::LogOverallTypePrediction( |
| 748 (predicted_type == UNKNOWN_TYPE ? match_empty_or_unknown |
| 749 : mismatch_empty_or_unknown), |
| 750 field_type, metric_type); |
| 715 continue; | 751 continue; |
| 752 } |
| 716 | 753 |
| 717 ++num_detected_field_types; | 754 ++num_detected_field_types; |
| 718 if (field->is_autofilled) | 755 if (field->is_autofilled) |
| 719 did_autofill_some_possible_fields = true; | 756 did_autofill_some_possible_fields = true; |
| 720 else | 757 else |
| 721 did_autofill_all_possible_fields = false; | 758 did_autofill_all_possible_fields = false; |
| 722 | 759 |
| 723 // Collapse field types that Chrome treats as identical, e.g. home and | 760 // Collapse field types that Chrome treats as identical, e.g. home and |
| 724 // billing address fields. | 761 // billing address fields. |
| 725 ServerFieldTypeSet collapsed_field_types; | 762 ServerFieldTypeSet collapsed_field_types; |
| 726 for (const auto& it : field_types) { | 763 for (const auto& it : field_types) { |
| 727 // Since we currently only support US phone numbers, the (city code + main | 764 // Since we currently only support US phone numbers, the (city code + main |
| 728 // digits) number is almost always identical to the whole phone number. | 765 // digits) number is almost always identical to the whole phone number. |
| 729 // TODO(isherman): Improve this logic once we add support for | 766 // TODO(isherman): Improve this logic once we add support for |
| 730 // international numbers. | 767 // international numbers. |
| 731 if (it == PHONE_HOME_CITY_AND_NUMBER) | 768 if (it == PHONE_HOME_CITY_AND_NUMBER) |
| 732 collapsed_field_types.insert(PHONE_HOME_WHOLE_NUMBER); | 769 collapsed_field_types.insert(PHONE_HOME_WHOLE_NUMBER); |
| 733 else | 770 else |
| 734 collapsed_field_types.insert(AutofillType(it).GetStorableType()); | 771 collapsed_field_types.insert(AutofillType(it).GetStorableType()); |
| 735 } | 772 } |
| 736 | 773 |
| 737 // Capture the field's type, if it is unambiguous. | 774 // Capture the field's type, if it is unambiguous. |
| 738 ServerFieldType field_type = UNKNOWN_TYPE; | 775 ServerFieldType field_type = UNKNOWN_TYPE; |
| 739 if (collapsed_field_types.size() == 1) | 776 if (collapsed_field_types.size() == 1) |
| 740 field_type = *collapsed_field_types.begin(); | 777 field_type = *collapsed_field_types.begin(); |
| 741 | 778 |
| 742 ServerFieldType heuristic_type = | 779 // Log heuristic, server, and overall type quality metrics. |
| 743 AutofillType(field->heuristic_type()).GetStorableType(); | |
| 744 ServerFieldType server_type = | |
| 745 AutofillType(field->server_type()).GetStorableType(); | |
| 746 ServerFieldType predicted_type = field->Type().GetStorableType(); | |
| 747 | |
| 748 // Log heuristic, server, and overall type quality metrics, independently of | |
| 749 // whether the field was autofilled. | |
| 750 const AutofillMetrics::QualityMetricType metric_type = | |
| 751 observed_submission ? AutofillMetrics::TYPE_SUBMISSION | |
| 752 : AutofillMetrics::TYPE_NO_SUBMISSION; | |
| 753 if (heuristic_type == UNKNOWN_TYPE) { | 780 if (heuristic_type == UNKNOWN_TYPE) { |
| 754 AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN, | 781 AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN, |
| 755 field_type, metric_type); | 782 field_type, metric_type); |
| 756 } else if (field_types.count(heuristic_type)) { | 783 } else if (field_types.count(heuristic_type)) { |
| 757 AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH, | 784 AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH, |
| 758 field_type, metric_type); | 785 field_type, metric_type); |
| 759 } else { | 786 } else { |
| 760 ++num_heuristic_mismatches; | 787 ++num_heuristic_mismatches; |
| 761 AutofillMetrics::LogHeuristicTypePrediction( | 788 AutofillMetrics::LogHeuristicTypePrediction( |
| 762 AutofillMetrics::TYPE_MISMATCH, field_type, metric_type); | 789 AutofillMetrics::TYPE_MISMATCH, field_type, metric_type); |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1339 filtered_strings[0].at(prefix_len)) { | 1366 filtered_strings[0].at(prefix_len)) { |
| 1340 // Mismatch found. | 1367 // Mismatch found. |
| 1341 return filtered_strings[i].substr(0, prefix_len); | 1368 return filtered_strings[i].substr(0, prefix_len); |
| 1342 } | 1369 } |
| 1343 } | 1370 } |
| 1344 } | 1371 } |
| 1345 return filtered_strings[0]; | 1372 return filtered_strings[0]; |
| 1346 } | 1373 } |
| 1347 | 1374 |
| 1348 } // namespace autofill | 1375 } // namespace autofill |
| OLD | NEW |