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> |
11 #include <utility> | 11 #include <utility> |
| 12 #include <vector> |
12 | 13 |
13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
14 #include "base/i18n/case_conversion.h" | 15 #include "base/i18n/case_conversion.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
16 #include "base/memory/ptr_util.h" | 17 #include "base/memory/ptr_util.h" |
17 #include "base/metrics/field_trial.h" | 18 #include "base/metrics/field_trial.h" |
18 #include "base/sha1.h" | 19 #include "base/sha1.h" |
19 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
20 #include "base/strings/string_split.h" | 21 #include "base/strings/string_split.h" |
21 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 for (const auto& field : fields_) { | 357 for (const auto& field : fields_) { |
357 const auto iter = field_type_map.find(field->unique_name()); | 358 const auto iter = field_type_map.find(field->unique_name()); |
358 if (iter != field_type_map.end()) | 359 if (iter != field_type_map.end()) |
359 field->set_heuristic_type(iter->second.BestHeuristicType()); | 360 field->set_heuristic_type(iter->second.BestHeuristicType()); |
360 } | 361 } |
361 } | 362 } |
362 | 363 |
363 UpdateAutofillCount(); | 364 UpdateAutofillCount(); |
364 IdentifySections(has_author_specified_sections_); | 365 IdentifySections(has_author_specified_sections_); |
365 | 366 |
| 367 std::vector<AutofillMetrics::DeveloperEngagementMetric> metrics; |
366 if (IsAutofillable()) { | 368 if (IsAutofillable()) { |
367 const auto metric = | 369 AutofillMetrics::DeveloperEngagementMetric metric = |
368 has_author_specified_types_ | 370 has_author_specified_types_ |
369 ? AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS | 371 ? AutofillMetrics::FILLABLE_FORM_PARSED_WITH_TYPE_HINTS |
370 : AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS; | 372 : AutofillMetrics::FILLABLE_FORM_PARSED_WITHOUT_TYPE_HINTS; |
| 373 metrics.push_back(metric); |
371 AutofillMetrics::LogDeveloperEngagementMetric(metric); | 374 AutofillMetrics::LogDeveloperEngagementMetric(metric); |
372 AutofillMetrics::LogDeveloperEngagementUkm(ukm_service, source_url(), | |
373 metric); | |
374 } | 375 } |
375 | 376 |
376 if (has_author_specified_upi_vpa_hint_) { | 377 if (has_author_specified_upi_vpa_hint_) { |
377 AutofillMetrics::LogDeveloperEngagementMetric( | 378 AutofillMetrics::LogDeveloperEngagementMetric( |
378 AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT); | 379 AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT); |
379 AutofillMetrics::LogDeveloperEngagementUkm( | 380 metrics.push_back(AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT); |
380 ukm_service, source_url(), AutofillMetrics::FORM_CONTAINS_UPI_VPA_HINT); | |
381 } | 381 } |
382 | 382 |
| 383 AutofillMetrics::LogDeveloperEngagementUkm(ukm_service, source_url(), |
| 384 metrics); |
| 385 |
383 AutofillMetrics::LogDetermineHeuristicTypesTiming( | 386 AutofillMetrics::LogDetermineHeuristicTypesTiming( |
384 base::TimeTicks::Now() - determine_heuristic_types_start_time); | 387 base::TimeTicks::Now() - determine_heuristic_types_start_time); |
385 } | 388 } |
386 | 389 |
387 bool FormStructure::EncodeUploadRequest( | 390 bool FormStructure::EncodeUploadRequest( |
388 const ServerFieldTypeSet& available_field_types, | 391 const ServerFieldTypeSet& available_field_types, |
389 bool form_was_autofilled, | 392 bool form_was_autofilled, |
390 const std::string& login_form_signature, | 393 const std::string& login_form_signature, |
391 bool observed_submission, | 394 bool observed_submission, |
392 AutofillUploadContents* upload) const { | 395 AutofillUploadContents* upload) const { |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 UpdateAutofillCount(); | 677 UpdateAutofillCount(); |
675 | 678 |
676 // The form signature should match between query and upload requests to the | 679 // The form signature should match between query and upload requests to the |
677 // server. On many websites, form elements are dynamically added, removed, or | 680 // server. On many websites, form elements are dynamically added, removed, or |
678 // rearranged via JavaScript between page load and form submission, so we | 681 // rearranged via JavaScript between page load and form submission, so we |
679 // copy over the |form_signature_field_names_| corresponding to the query | 682 // copy over the |form_signature_field_names_| corresponding to the query |
680 // request. | 683 // request. |
681 form_signature_ = cached_form.form_signature_; | 684 form_signature_ = cached_form.form_signature_; |
682 } | 685 } |
683 | 686 |
684 void FormStructure::LogQualityMetrics(const base::TimeTicks& load_time, | 687 void FormStructure::LogQualityMetrics( |
685 const base::TimeTicks& interaction_time, | 688 const base::TimeTicks& load_time, |
686 const base::TimeTicks& submission_time, | 689 const base::TimeTicks& interaction_time, |
687 rappor::RapporServiceImpl* rappor_service, | 690 const base::TimeTicks& submission_time, |
688 bool did_show_suggestions, | 691 rappor::RapporServiceImpl* rappor_service, |
689 bool observed_submission) const { | 692 AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger, |
| 693 bool did_show_suggestions, |
| 694 bool observed_submission) const { |
690 size_t num_detected_field_types = 0; | 695 size_t num_detected_field_types = 0; |
691 size_t num_server_mismatches = 0; | 696 size_t num_server_mismatches = 0; |
692 size_t num_heuristic_mismatches = 0; | 697 size_t num_heuristic_mismatches = 0; |
693 size_t num_edited_autofilled_fields = 0; | 698 size_t num_edited_autofilled_fields = 0; |
694 bool did_autofill_all_possible_fields = true; | 699 bool did_autofill_all_possible_fields = true; |
695 bool did_autofill_some_possible_fields = false; | 700 bool did_autofill_some_possible_fields = false; |
696 for (size_t i = 0; i < field_count(); ++i) { | 701 for (size_t i = 0; i < field_count(); ++i) { |
697 auto* const field = this->field(i); | 702 auto* const field = this->field(i); |
698 | 703 |
699 // No further logging for password fields. Those are primarily related to a | 704 // No further logging for password fields. Those are primarily related to a |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
785 field_type, metric_type); | 790 field_type, metric_type); |
786 } | 791 } |
787 } | 792 } |
788 | 793 |
789 AutofillMetrics::LogNumberOfEditedAutofilledFields( | 794 AutofillMetrics::LogNumberOfEditedAutofilledFields( |
790 num_edited_autofilled_fields, observed_submission); | 795 num_edited_autofilled_fields, observed_submission); |
791 | 796 |
792 // We log "submission" and duration metrics if we are here after observing a | 797 // We log "submission" and duration metrics if we are here after observing a |
793 // submission event. | 798 // submission event. |
794 if (observed_submission) { | 799 if (observed_submission) { |
| 800 AutofillMetrics::AutofillFormSubmittedState state; |
795 if (num_detected_field_types < kRequiredFieldsForPredictionRoutines) { | 801 if (num_detected_field_types < kRequiredFieldsForPredictionRoutines) { |
796 AutofillMetrics::LogAutofillFormSubmittedState( | 802 state = AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA; |
797 AutofillMetrics::NON_FILLABLE_FORM_OR_NEW_DATA); | |
798 } else { | 803 } else { |
799 if (did_autofill_all_possible_fields) { | 804 if (did_autofill_all_possible_fields) { |
800 AutofillMetrics::LogAutofillFormSubmittedState( | 805 state = AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL; |
801 AutofillMetrics::FILLABLE_FORM_AUTOFILLED_ALL); | |
802 } else if (did_autofill_some_possible_fields) { | 806 } else if (did_autofill_some_possible_fields) { |
803 AutofillMetrics::LogAutofillFormSubmittedState( | 807 state = AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME; |
804 AutofillMetrics::FILLABLE_FORM_AUTOFILLED_SOME); | |
805 } else if (!did_show_suggestions) { | 808 } else if (!did_show_suggestions) { |
806 AutofillMetrics::LogAutofillFormSubmittedState( | 809 state = AutofillMetrics:: |
807 AutofillMetrics:: | 810 FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS; |
808 FILLABLE_FORM_AUTOFILLED_NONE_DID_NOT_SHOW_SUGGESTIONS); | |
809 } else { | 811 } else { |
810 AutofillMetrics::LogAutofillFormSubmittedState( | 812 state = |
811 AutofillMetrics:: | 813 AutofillMetrics::FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS; |
812 FILLABLE_FORM_AUTOFILLED_NONE_DID_SHOW_SUGGESTIONS); | |
813 } | 814 } |
814 | 815 |
815 // Log some RAPPOR metrics for problematic cases. | 816 // Log some RAPPOR metrics for problematic cases. |
816 if (num_server_mismatches >= kNumberOfMismatchesThreshold) { | 817 if (num_server_mismatches >= kNumberOfMismatchesThreshold) { |
817 rappor::SampleDomainAndRegistryFromGURL( | 818 rappor::SampleDomainAndRegistryFromGURL( |
818 rappor_service, "Autofill.HighNumberOfServerMismatches", | 819 rappor_service, "Autofill.HighNumberOfServerMismatches", |
819 source_url_); | 820 source_url_); |
820 } | 821 } |
821 if (num_heuristic_mismatches >= kNumberOfMismatchesThreshold) { | 822 if (num_heuristic_mismatches >= kNumberOfMismatchesThreshold) { |
822 rappor::SampleDomainAndRegistryFromGURL( | 823 rappor::SampleDomainAndRegistryFromGURL( |
(...skipping 26 matching lines...) Expand all Loading... |
849 base::TimeDelta elapsed = submission_time - interaction_time; | 850 base::TimeDelta elapsed = submission_time - interaction_time; |
850 if (did_autofill_some_possible_fields) { | 851 if (did_autofill_some_possible_fields) { |
851 AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill( | 852 AutofillMetrics::LogFormFillDurationFromInteractionWithAutofill( |
852 elapsed); | 853 elapsed); |
853 } else { | 854 } else { |
854 AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill( | 855 AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill( |
855 elapsed); | 856 elapsed); |
856 } | 857 } |
857 } | 858 } |
858 } | 859 } |
| 860 if (form_interactions_ukm_logger->url() != source_url()) |
| 861 form_interactions_ukm_logger->set_url(source_url()); |
| 862 AutofillMetrics::LogAutofillFormSubmittedState( |
| 863 state, form_interactions_ukm_logger); |
859 } | 864 } |
860 } | 865 } |
861 | 866 |
862 void FormStructure::LogQualityMetricsBasedOnAutocomplete() const { | 867 void FormStructure::LogQualityMetricsBasedOnAutocomplete() const { |
863 for (const auto& field : fields_) { | 868 for (const auto& field : fields_) { |
864 if (field->html_type() != HTML_TYPE_UNSPECIFIED && | 869 if (field->html_type() != HTML_TYPE_UNSPECIFIED && |
865 field->html_type() != HTML_TYPE_UNRECOGNIZED) { | 870 field->html_type() != HTML_TYPE_UNRECOGNIZED) { |
866 // The type inferred by the autocomplete attribute. | 871 // The type inferred by the autocomplete attribute. |
867 AutofillType type(field->html_type(), field->html_mode()); | 872 AutofillType type(field->html_type(), field->html_mode()); |
868 ServerFieldType actual_field_type = type.GetStorableType(); | 873 ServerFieldType actual_field_type = type.GetStorableType(); |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 filtered_strings[0].at(prefix_len)) { | 1344 filtered_strings[0].at(prefix_len)) { |
1340 // Mismatch found. | 1345 // Mismatch found. |
1341 return filtered_strings[i].substr(0, prefix_len); | 1346 return filtered_strings[i].substr(0, prefix_len); |
1342 } | 1347 } |
1343 } | 1348 } |
1344 } | 1349 } |
1345 return filtered_strings[0]; | 1350 return filtered_strings[0]; |
1346 } | 1351 } |
1347 | 1352 |
1348 } // namespace autofill | 1353 } // namespace autofill |
OLD | NEW |