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

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

Issue 2800853004: UKM that threads together multiple form interaction events. (Closed)
Patch Set: Logs each form interaction event in a separate UkmEntry, includes time_delta as a metric. Created 3 years, 8 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>
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698