Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: components/autofill/core/browser/form_structure.cc

Issue 2003563003: [Autofill] Quality metric based on autocomplete attributes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: histograms.xml Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 493
494 // In some cases *successful* response does not return all the fields. 494 // In some cases *successful* response does not return all the fields.
495 // Quit the update of the types then. 495 // Quit the update of the types then.
496 if (current_field == response.field().end()) 496 if (current_field == response.field().end())
497 break; 497 break;
498 498
499 ServerFieldType field_type = 499 ServerFieldType field_type =
500 static_cast<ServerFieldType>(current_field->autofill_type()); 500 static_cast<ServerFieldType>(current_field->autofill_type());
501 query_response_has_no_server_data &= field_type == NO_SERVER_DATA; 501 query_response_has_no_server_data &= field_type == NO_SERVER_DATA;
502 502
503 // If |form->has_author_specified_types| only password fields should be 503 // UNKNOWN_TYPE is reserved for use by the client.
504 // updated. 504 DCHECK_NE(field_type, UNKNOWN_TYPE);
505 if (!form->has_author_specified_types_ ||
506 field->form_control_type == "password") {
507 // UNKNOWN_TYPE is reserved for use by the client.
508 DCHECK_NE(field_type, UNKNOWN_TYPE);
509 505
510 ServerFieldType heuristic_type = field->heuristic_type(); 506 ServerFieldType heuristic_type = field->heuristic_type();
511 if (heuristic_type != UNKNOWN_TYPE) 507 if (heuristic_type != UNKNOWN_TYPE)
512 heuristics_detected_fillable_field = true; 508 heuristics_detected_fillable_field = true;
513 509
514 field->set_server_type(field_type); 510 field->set_server_type(field_type);
515 if (heuristic_type != field->Type().GetStorableType()) 511 if (heuristic_type != field->Type().GetStorableType())
516 query_response_overrode_heuristics = true; 512 query_response_overrode_heuristics = true;
517 }
518 513
519 ++current_field; 514 ++current_field;
520 } 515 }
521 516
522 AutofillMetrics::LogServerResponseHasDataForForm( 517 AutofillMetrics::LogServerResponseHasDataForForm(
523 !query_response_has_no_server_data); 518 !query_response_has_no_server_data);
524 if (query_response_has_no_server_data && form->source_url().is_valid()) { 519 if (query_response_has_no_server_data && form->source_url().is_valid()) {
525 rappor::SampleDomainAndRegistryFromGURL( 520 rappor::SampleDomainAndRegistryFromGURL(
526 rappor_service, "Autofill.QueryResponseHasNoServerDataForForm", 521 rappor_service, "Autofill.QueryResponseHasNoServerDataForForm",
527 form->source_url()); 522 form->source_url());
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 field_type = *collapsed_field_types.begin(); 722 field_type = *collapsed_field_types.begin();
728 723
729 ServerFieldType heuristic_type = 724 ServerFieldType heuristic_type =
730 AutofillType(field->heuristic_type()).GetStorableType(); 725 AutofillType(field->heuristic_type()).GetStorableType();
731 ServerFieldType server_type = 726 ServerFieldType server_type =
732 AutofillType(field->server_type()).GetStorableType(); 727 AutofillType(field->server_type()).GetStorableType();
733 ServerFieldType predicted_type = field->Type().GetStorableType(); 728 ServerFieldType predicted_type = field->Type().GetStorableType();
734 729
735 // Log heuristic, server, and overall type quality metrics, independently of 730 // Log heuristic, server, and overall type quality metrics, independently of
736 // whether the field was autofilled. 731 // whether the field was autofilled.
732 const AutofillMetrics::QualityMetricType metric_type =
733 observed_submission ? AutofillMetrics::TYPE_SUBMISSION
734 : AutofillMetrics::TYPE_NO_SUBMISSION;
737 if (heuristic_type == UNKNOWN_TYPE) { 735 if (heuristic_type == UNKNOWN_TYPE) {
738 AutofillMetrics::LogHeuristicTypePrediction( 736 AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
739 AutofillMetrics::TYPE_UNKNOWN, field_type, observed_submission); 737 field_type, metric_type);
740 } else if (field_types.count(heuristic_type)) { 738 } else if (field_types.count(heuristic_type)) {
741 AutofillMetrics::LogHeuristicTypePrediction( 739 AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH,
742 AutofillMetrics::TYPE_MATCH, field_type, observed_submission); 740 field_type, metric_type);
743 } else { 741 } else {
744 ++num_heuristic_mismatches; 742 ++num_heuristic_mismatches;
745 AutofillMetrics::LogHeuristicTypePrediction( 743 AutofillMetrics::LogHeuristicTypePrediction(
746 AutofillMetrics::TYPE_MISMATCH, field_type, observed_submission); 744 AutofillMetrics::TYPE_MISMATCH, field_type, metric_type);
747 } 745 }
748 746
749 if (server_type == NO_SERVER_DATA) { 747 if (server_type == NO_SERVER_DATA) {
750 AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN, 748 AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
751 field_type, observed_submission); 749 field_type, metric_type);
752 } else if (field_types.count(server_type)) { 750 } else if (field_types.count(server_type)) {
753 AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_MATCH, 751 AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_MATCH,
754 field_type, observed_submission); 752 field_type, metric_type);
755 } else { 753 } else {
756 ++num_server_mismatches; 754 ++num_server_mismatches;
757 AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH, 755 AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH,
758 field_type, observed_submission); 756 field_type, metric_type);
759 } 757 }
760 758
761 if (predicted_type == UNKNOWN_TYPE) { 759 if (predicted_type == UNKNOWN_TYPE) {
762 AutofillMetrics::LogOverallTypePrediction( 760 AutofillMetrics::LogOverallTypePrediction(AutofillMetrics::TYPE_UNKNOWN,
763 AutofillMetrics::TYPE_UNKNOWN, field_type, observed_submission); 761 field_type, metric_type);
764 } else if (field_types.count(predicted_type)) { 762 } else if (field_types.count(predicted_type)) {
765 AutofillMetrics::LogOverallTypePrediction( 763 AutofillMetrics::LogOverallTypePrediction(AutofillMetrics::TYPE_MATCH,
766 AutofillMetrics::TYPE_MATCH, field_type, observed_submission); 764 field_type, metric_type);
767 } else { 765 } else {
768 AutofillMetrics::LogOverallTypePrediction( 766 AutofillMetrics::LogOverallTypePrediction(AutofillMetrics::TYPE_MISMATCH,
769 AutofillMetrics::TYPE_MISMATCH, field_type, observed_submission); 767 field_type, metric_type);
770 } 768 }
771 } 769 }
772 770
773 AutofillMetrics::LogNumberOfEditedAutofilledFields( 771 AutofillMetrics::LogNumberOfEditedAutofilledFields(
774 num_edited_autofilled_fields, observed_submission); 772 num_edited_autofilled_fields, observed_submission);
775 773
776 // We log "submission" and duration metrics if we are here after observing a 774 // We log "submission" and duration metrics if we are here after observing a
777 // submission event. 775 // submission event.
778 if (observed_submission) { 776 if (observed_submission) {
779 if (num_detected_field_types < kRequiredFieldsForPredictionRoutines) { 777 if (num_detected_field_types < kRequiredFieldsForPredictionRoutines) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 elapsed); 834 elapsed);
837 } else { 835 } else {
838 AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill( 836 AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill(
839 elapsed); 837 elapsed);
840 } 838 }
841 } 839 }
842 } 840 }
843 } 841 }
844 } 842 }
845 843
844 void FormStructure::LogQualityMetricsBasedOnAutocomplete() const {
845 for (const AutofillField* field : fields_) {
846 if (field->html_type() != HTML_TYPE_UNSPECIFIED &&
847 field->html_type() != HTML_TYPE_UNRECOGNIZED) {
848 // The type inferred by the autocomplete attribute.
849 AutofillType type(field->html_type(), field->html_mode());
850 ServerFieldType actual_field_type = type.GetStorableType();
851
852 const AutofillMetrics::QualityMetricType metric_type =
853 AutofillMetrics::TYPE_AUTOCOMPLETE_BASED;
854 // Log the quality of our heuristics predictions.
855 if (field->heuristic_type() == UNKNOWN_TYPE) {
856 AutofillMetrics::LogHeuristicTypePrediction(
857 AutofillMetrics::TYPE_UNKNOWN, actual_field_type, metric_type);
858 } else if (field->heuristic_type() == actual_field_type) {
859 AutofillMetrics::LogHeuristicTypePrediction(
860 AutofillMetrics::TYPE_MATCH, actual_field_type, metric_type);
861 } else {
862 AutofillMetrics::LogHeuristicTypePrediction(
863 AutofillMetrics::TYPE_MISMATCH, actual_field_type, metric_type);
864 }
865
866 // Log the quality of our server predictions.
867 if (field->server_type() == NO_SERVER_DATA) {
868 AutofillMetrics::LogServerTypePrediction(
869 AutofillMetrics::TYPE_UNKNOWN, actual_field_type, metric_type);
870 } else if (field->server_type() == actual_field_type) {
871 AutofillMetrics::LogServerTypePrediction(
872 AutofillMetrics::TYPE_MATCH, actual_field_type, metric_type);
873 } else {
874 AutofillMetrics::LogServerTypePrediction(
875 AutofillMetrics::TYPE_MISMATCH, actual_field_type, metric_type);
876 }
877 }
878 }
879 }
880
846 void FormStructure::ParseFieldTypesFromAutocompleteAttributes() { 881 void FormStructure::ParseFieldTypesFromAutocompleteAttributes() {
847 const std::string kDefaultSection = "-default"; 882 const std::string kDefaultSection = "-default";
848 883
849 has_author_specified_types_ = false; 884 has_author_specified_types_ = false;
850 has_author_specified_sections_ = false; 885 has_author_specified_sections_ = false;
851 for (AutofillField* field : fields_) { 886 for (AutofillField* field : fields_) {
852 // To prevent potential section name collisions, add a default suffix for 887 // To prevent potential section name collisions, add a default suffix for
853 // other fields. Without this, 'autocomplete' attribute values 888 // other fields. Without this, 'autocomplete' attribute values
854 // "section--shipping street-address" and "shipping street-address" would be 889 // "section--shipping street-address" and "shipping street-address" would be
855 // parsed identically, given the section handling code below. We do this 890 // parsed identically, given the section handling code below. We do this
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
1330 filtered_strings[0].at(prefix_len)) { 1365 filtered_strings[0].at(prefix_len)) {
1331 // Mismatch found. 1366 // Mismatch found.
1332 return filtered_strings[i].substr(0, prefix_len); 1367 return filtered_strings[i].substr(0, prefix_len);
1333 } 1368 }
1334 } 1369 }
1335 } 1370 }
1336 return filtered_strings[0]; 1371 return filtered_strings[0];
1337 } 1372 }
1338 1373
1339 } // namespace autofill 1374 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/form_structure.h ('k') | components/autofill/core/browser/form_structure_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698