| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/logging.h" | 10 #include "base/logging.h" |
| (...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 643 DCHECK_EQ(cached_form.source_url_, source_url_); | 643 DCHECK_EQ(cached_form.source_url_, source_url_); |
| 644 DCHECK_EQ(cached_form.target_url_, target_url_); | 644 DCHECK_EQ(cached_form.target_url_, target_url_); |
| 645 form_signature_field_names_ = cached_form.form_signature_field_names_; | 645 form_signature_field_names_ = cached_form.form_signature_field_names_; |
| 646 } | 646 } |
| 647 | 647 |
| 648 void FormStructure::LogQualityMetrics( | 648 void FormStructure::LogQualityMetrics( |
| 649 const AutofillMetrics& metric_logger) const { | 649 const AutofillMetrics& metric_logger) const { |
| 650 std::string experiment_id = server_experiment_id(); | 650 std::string experiment_id = server_experiment_id(); |
| 651 metric_logger.LogServerExperimentIdForUpload(experiment_id); | 651 metric_logger.LogServerExperimentIdForUpload(experiment_id); |
| 652 | 652 |
| 653 size_t num_detected_field_types = 0; |
| 654 bool did_autofill_all_possible_fields = true; |
| 655 bool did_autofill_some_possible_fields = false; |
| 653 for (size_t i = 0; i < field_count(); ++i) { | 656 for (size_t i = 0; i < field_count(); ++i) { |
| 654 const AutofillField* field = this->field(i); | 657 const AutofillField* field = this->field(i); |
| 655 metric_logger.LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, | 658 metric_logger.LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, |
| 656 experiment_id); | 659 experiment_id); |
| 657 | 660 |
| 658 // No further logging for empty fields nor for fields where the entered data | 661 // No further logging for empty fields nor for fields where the entered data |
| 659 // does not appear to already exist in the user's stored Autofill data. | 662 // does not appear to already exist in the user's stored Autofill data. |
| 660 const FieldTypeSet& field_types = field->possible_types(); | 663 const FieldTypeSet& field_types = field->possible_types(); |
| 661 DCHECK(!field_types.empty()); | 664 DCHECK(!field_types.empty()); |
| 662 if (field_types.count(EMPTY_TYPE) || field_types.count(UNKNOWN_TYPE)) | 665 if (field_types.count(EMPTY_TYPE) || field_types.count(UNKNOWN_TYPE)) |
| 663 continue; | 666 continue; |
| 664 | 667 |
| 668 ++num_detected_field_types; |
| 669 if (field->is_autofilled) |
| 670 did_autofill_some_possible_fields = true; |
| 671 else |
| 672 did_autofill_all_possible_fields = false; |
| 673 |
| 665 // Collapse field types that Chrome treats as identical, e.g. home and | 674 // Collapse field types that Chrome treats as identical, e.g. home and |
| 666 // billing address fields. | 675 // billing address fields. |
| 667 FieldTypeSet collapsed_field_types; | 676 FieldTypeSet collapsed_field_types; |
| 668 for (FieldTypeSet::const_iterator it = field_types.begin(); | 677 for (FieldTypeSet::const_iterator it = field_types.begin(); |
| 669 it != field_types.end(); | 678 it != field_types.end(); |
| 670 ++it) { | 679 ++it) { |
| 671 // Since we currently only support US phone numbers, the (city code + main | 680 // Since we currently only support US phone numbers, the (city code + main |
| 672 // digits) number is almost always identical to the whole phone number. | 681 // digits) number is almost always identical to the whole phone number. |
| 673 // TODO(isherman): Improve this logic once we add support for | 682 // TODO(isherman): Improve this logic once we add support for |
| 674 // international numbers. | 683 // international numbers. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 758 metric_logger.LogQualityMetric( | 767 metric_logger.LogQualityMetric( |
| 759 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH, | 768 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MATCH, |
| 760 experiment_id); | 769 experiment_id); |
| 761 } else { | 770 } else { |
| 762 metric_logger.LogQualityMetric( | 771 metric_logger.LogQualityMetric( |
| 763 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH, | 772 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH, |
| 764 experiment_id); | 773 experiment_id); |
| 765 } | 774 } |
| 766 } | 775 } |
| 767 } | 776 } |
| 768 } | |
| 769 | 777 |
| 770 void FormStructure::set_possible_types(size_t index, | 778 if (num_detected_field_types < kRequiredFillableFields) { |
| 771 const FieldTypeSet& types) { | 779 metric_logger.LogUserHappinessMetric( |
| 772 if (index >= fields_.size()) { | 780 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM); |
| 773 NOTREACHED(); | 781 } else if (did_autofill_all_possible_fields) { |
| 774 return; | 782 metric_logger.LogUserHappinessMetric( |
| 783 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL); |
| 784 } else if (did_autofill_some_possible_fields) { |
| 785 metric_logger.LogUserHappinessMetric( |
| 786 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME); |
| 787 } else { |
| 788 metric_logger.LogUserHappinessMetric( |
| 789 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE); |
| 775 } | 790 } |
| 776 | |
| 777 fields_[index]->set_possible_types(types); | |
| 778 } | 791 } |
| 779 | 792 |
| 780 const AutofillField* FormStructure::field(size_t index) const { | 793 const AutofillField* FormStructure::field(size_t index) const { |
| 781 if (index >= fields_.size()) { | 794 if (index >= fields_.size()) { |
| 782 NOTREACHED(); | 795 NOTREACHED(); |
| 783 return NULL; | 796 return NULL; |
| 784 } | 797 } |
| 785 | 798 |
| 786 return fields_[index]; | 799 return fields_[index]; |
| 787 } | 800 } |
| 788 | 801 |
| 802 AutofillField* FormStructure::field(size_t index) { |
| 803 return const_cast<AutofillField*>( |
| 804 static_cast<const FormStructure*>(this)->field(index)); |
| 805 } |
| 806 |
| 789 size_t FormStructure::field_count() const { | 807 size_t FormStructure::field_count() const { |
| 790 return fields_.size(); | 808 return fields_.size(); |
| 791 } | 809 } |
| 792 | 810 |
| 793 std::string FormStructure::server_experiment_id() const { | 811 std::string FormStructure::server_experiment_id() const { |
| 794 return server_experiment_id_; | 812 return server_experiment_id_; |
| 795 } | 813 } |
| 796 | 814 |
| 797 bool FormStructure::operator==(const FormData& form) const { | 815 bool FormStructure::operator==(const FormData& form) const { |
| 798 // TODO(jhawkins): Is this enough to differentiate a form? | 816 // TODO(jhawkins): Is this enough to differentiate a form? |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 if (current_type != UNKNOWN_TYPE && already_saw_current_type) { | 960 if (current_type != UNKNOWN_TYPE && already_saw_current_type) { |
| 943 // We reached the end of a section, so start a new section. | 961 // We reached the end of a section, so start a new section. |
| 944 seen_types.clear(); | 962 seen_types.clear(); |
| 945 current_section = (*field)->unique_name(); | 963 current_section = (*field)->unique_name(); |
| 946 } | 964 } |
| 947 | 965 |
| 948 seen_types.insert(current_type); | 966 seen_types.insert(current_type); |
| 949 (*field)->set_section(current_section); | 967 (*field)->set_section(current_section); |
| 950 } | 968 } |
| 951 } | 969 } |
| OLD | NEW |