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

Side by Side Diff: chrome/browser/autofill/form_structure.cc

Issue 7740070: Add metrics to measure time elapsed between form load and form submission with or without Autofill. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix tests Created 9 years, 3 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 | Annotate | Revision Log
OLDNEW
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"
11 #include "base/sha1.h" 11 #include "base/sha1.h"
12 #include "base/stringprintf.h" 12 #include "base/stringprintf.h"
13 #include "base/string_number_conversions.h" 13 #include "base/string_number_conversions.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/time.h"
15 #include "base/utf_string_conversions.h" 16 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/autofill/autofill_metrics.h" 17 #include "chrome/browser/autofill/autofill_metrics.h"
17 #include "chrome/browser/autofill/autofill_type.h" 18 #include "chrome/browser/autofill/autofill_type.h"
18 #include "chrome/browser/autofill/autofill_xml_parser.h" 19 #include "chrome/browser/autofill/autofill_xml_parser.h"
19 #include "chrome/browser/autofill/field_types.h" 20 #include "chrome/browser/autofill/field_types.h"
20 #include "chrome/browser/autofill/form_field.h" 21 #include "chrome/browser/autofill/form_field.h"
21 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 22 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
22 #include "webkit/glue/form_data.h" 23 #include "webkit/glue/form_data.h"
23 #include "webkit/glue/form_data_predictions.h" 24 #include "webkit/glue/form_data_predictions.h"
24 #include "webkit/glue/form_field.h" 25 #include "webkit/glue/form_field.h"
(...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 // rearranged via JavaScript between page load and form submission, so we 640 // rearranged via JavaScript between page load and form submission, so we
640 // copy over the |form_signature_field_names_| corresponding to the query 641 // copy over the |form_signature_field_names_| corresponding to the query
641 // request. 642 // request.
642 DCHECK_EQ(cached_form.form_name_, form_name_); 643 DCHECK_EQ(cached_form.form_name_, form_name_);
643 DCHECK_EQ(cached_form.source_url_, source_url_); 644 DCHECK_EQ(cached_form.source_url_, source_url_);
644 DCHECK_EQ(cached_form.target_url_, target_url_); 645 DCHECK_EQ(cached_form.target_url_, target_url_);
645 form_signature_field_names_ = cached_form.form_signature_field_names_; 646 form_signature_field_names_ = cached_form.form_signature_field_names_;
646 } 647 }
647 648
648 void FormStructure::LogQualityMetrics( 649 void FormStructure::LogQualityMetrics(
649 const AutofillMetrics& metric_logger) const { 650 const AutofillMetrics& metric_logger,
651 const base::TimeTicks& load_time,
652 const base::TimeTicks& interaction_time,
653 const base::TimeTicks& submission_time) const {
650 std::string experiment_id = server_experiment_id(); 654 std::string experiment_id = server_experiment_id();
651 metric_logger.LogServerExperimentIdForUpload(experiment_id); 655 metric_logger.LogServerExperimentIdForUpload(experiment_id);
652 656
653 size_t num_detected_field_types = 0; 657 size_t num_detected_field_types = 0;
654 bool did_autofill_all_possible_fields = true; 658 bool did_autofill_all_possible_fields = true;
655 bool did_autofill_some_possible_fields = false; 659 bool did_autofill_some_possible_fields = false;
656 for (size_t i = 0; i < field_count(); ++i) { 660 for (size_t i = 0; i < field_count(); ++i) {
657 const AutofillField* field = this->field(i); 661 const AutofillField* field = this->field(i);
658 metric_logger.LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED, 662 metric_logger.LogQualityMetric(AutofillMetrics::FIELD_SUBMITTED,
659 experiment_id); 663 experiment_id);
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
771 metric_logger.LogQualityMetric( 775 metric_logger.LogQualityMetric(
772 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH, 776 AutofillMetrics::NOT_AUTOFILLED_SERVER_TYPE_MISMATCH,
773 experiment_id); 777 experiment_id);
774 } 778 }
775 } 779 }
776 } 780 }
777 781
778 if (num_detected_field_types < kRequiredFillableFields) { 782 if (num_detected_field_types < kRequiredFillableFields) {
779 metric_logger.LogUserHappinessMetric( 783 metric_logger.LogUserHappinessMetric(
780 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM); 784 AutofillMetrics::SUBMITTED_NON_FILLABLE_FORM);
781 } else if (did_autofill_all_possible_fields) {
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 { 785 } else {
788 metric_logger.LogUserHappinessMetric( 786 if (did_autofill_all_possible_fields) {
789 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE); 787 metric_logger.LogUserHappinessMetric(
788 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_ALL);
789 } else if (did_autofill_some_possible_fields) {
790 metric_logger.LogUserHappinessMetric(
791 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_SOME);
792 } else {
793 metric_logger.LogUserHappinessMetric(
794 AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE);
795 }
796
797 // Unlike the other times, the |submission_time| should always be available.
798 DCHECK(!submission_time.is_null());
799
800 // The |load_time| might be unset, in the case that the form was dynamically
801 // added to the DOM.
802 if (!load_time.is_null()) {
803 // Submission should always chronologically follow form load.
804 DCHECK(submission_time > load_time);
805 base::TimeDelta elapsed = submission_time - load_time;
806 if (did_autofill_some_possible_fields)
807 metric_logger.LogFormFillDurationFromLoadWithAutofill(elapsed);
808 else
809 metric_logger.LogFormFillDurationFromLoadWithoutAutofill(elapsed);
810 }
811
812 // The |interaction_time| might be unset, in the case that the user
813 // submitted a blank form.
814 if (!interaction_time.is_null()) {
jar (doing other things) 2011/09/02 01:48:33 (optional) personal style nit: I really like early
Ilya Sherman 2011/09/02 06:57:54 I generally agree with you. I decided on the nest
815 // Submission should always chronologically follow interaction.
816 DCHECK(submission_time > interaction_time);
817 base::TimeDelta elapsed = submission_time - interaction_time;
818 if (did_autofill_some_possible_fields) {
819 metric_logger.LogFormFillDurationFromInteractionWithAutofill(elapsed);
820 } else {
821 metric_logger.LogFormFillDurationFromInteractionWithoutAutofill(
822 elapsed);
823 }
824 }
790 } 825 }
791 } 826 }
792 827
793 const AutofillField* FormStructure::field(size_t index) const { 828 const AutofillField* FormStructure::field(size_t index) const {
794 if (index >= fields_.size()) { 829 if (index >= fields_.size()) {
795 NOTREACHED(); 830 NOTREACHED();
796 return NULL; 831 return NULL;
797 } 832 }
798 833
799 return fields_[index]; 834 return fields_[index];
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 if (current_type != UNKNOWN_TYPE && already_saw_current_type) { 995 if (current_type != UNKNOWN_TYPE && already_saw_current_type) {
961 // We reached the end of a section, so start a new section. 996 // We reached the end of a section, so start a new section.
962 seen_types.clear(); 997 seen_types.clear();
963 current_section = (*field)->unique_name(); 998 current_section = (*field)->unique_name();
964 } 999 }
965 1000
966 seen_types.insert(current_type); 1001 seen_types.insert(current_type);
967 (*field)->set_section(current_section); 1002 (*field)->set_section(current_section);
968 } 1003 }
969 } 1004 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698