Chromium Code Reviews| Index: components/autofill/core/browser/autofill_metrics.cc |
| diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc |
| index 7159c789802d7578c54f72d0337c60f364d5efb8..2ee249a2f1b10dd27f0de2dd78938273364724e8 100644 |
| --- a/components/autofill/core/browser/autofill_metrics.cc |
| +++ b/components/autofill/core/browser/autofill_metrics.cc |
| @@ -49,6 +49,18 @@ const char kUKMIsEmptyMetricName[] = "IsEmpty"; |
| const char kUKMFormSubmittedEntryName[] = "Autofill.AutofillFormSubmitted"; |
| const char kUKMAutofillFormSubmittedStateMetricName[] = |
| "AutofillFormSubmittedState"; |
| +// |UkmEntry| for capturing field type prediction quality. |
| +const char kUKMFieldTypeEntryName[] = "Autofill.FieldTypeValidation"; |
| +const char kUKMFieldFillStatusEntryName[] = "Autofill.FieldFillStatus"; |
| +const char kUKMFormSignatureMetricName[] = "FormSignature"; |
| +const char kUKMFieldSignatureMetricName[] = "FieldSignature"; |
| +const char kUKMValidationEventMetricName[] = "ValidationEvent"; |
| +const char kUKMPredictionSourceMetricName[] = "PredictionSource"; |
| +const char kUKMPredictedTypeMetricName[] = "PredictedType"; |
| +const char kUKMActualTypeMetricName[] = "ActualType"; |
| +const char kUKMWasSuggestionShownMetricName[] = "WasSuggestionShown"; |
| +const char kUKMWasPreviouslyAutofilledMetricName[] = "WasPreviouslyAutofilled"; |
| + |
| } // namespace internal |
| namespace autofill { |
| @@ -277,6 +289,23 @@ void LogUMAHistogramLongTimes(const std::string& name, |
| histogram->AddTime(duration); |
| } |
| +const char* GetQualityMetricPredictionSource( |
| + AutofillMetrics::QualityMetricPredictionSource source) { |
| + switch (source) { |
| + default: |
| + case AutofillMetrics::PREDICTION_SOURCE_UNKNOWN: |
| + NOTREACHED(); |
| + return "Unknown"; |
| + |
| + case AutofillMetrics::PREDICTION_SOURCE_HEURISTIC: |
| + return "Heuristic"; |
| + case AutofillMetrics::PREDICTION_SOURCE_SERVER: |
| + return "Server"; |
| + case AutofillMetrics::PREDICTION_SOURCE_OVERALL: |
| + return "Overall"; |
| + } |
| +} |
| + |
| const char* GetQualityMetricTypeSuffix( |
| AutofillMetrics::QualityMetricType metric_type) { |
| switch (metric_type) { |
| @@ -344,12 +373,15 @@ ServerFieldType GetActualFieldType(const ServerFieldTypeSet& possible_types, |
| // respectively). May log a suffixed version of the metric depending on |
| // |metric_type|. |
| void LogPredictionQualityMetrics( |
| - const base::StringPiece& source, |
| - const ServerFieldTypeSet& possible_types, |
| + AutofillMetrics::QualityMetricPredictionSource prediction_source, |
| ServerFieldType predicted_type, |
| + AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger, |
| + const FormStructure& form, |
| + const AutofillField& field, |
| AutofillMetrics::QualityMetricType metric_type) { |
| // Generate histogram names. |
| - const char* const suffix = GetQualityMetricTypeSuffix(metric_type); |
| + const char* source = GetQualityMetricPredictionSource(prediction_source); |
| + const char* suffix = GetQualityMetricTypeSuffix(metric_type); |
| std::string raw_data_histogram = |
| base::JoinString({"Autofill.FieldPrediction.", source, suffix}, ""); |
| std::string aggregate_histogram = base::JoinString( |
| @@ -357,6 +389,13 @@ void LogPredictionQualityMetrics( |
| std::string type_specific_histogram = base::JoinString( |
| {"Autofill.FieldPredictionQuality.ByFieldType.", source, suffix}, ""); |
| + const ServerFieldTypeSet& possible_types = |
| + metric_type == AutofillMetrics::TYPE_AUTOCOMPLETE_BASED |
| + ? ServerFieldTypeSet{AutofillType(field.html_type(), |
| + field.html_mode()) |
| + .GetStorableType()} |
| + : field.possible_types(); |
| + |
| // Get the best type classification we can for the field. |
| ServerFieldType actual_type = |
| GetActualFieldType(possible_types, predicted_type); |
| @@ -369,6 +408,10 @@ void LogPredictionQualityMetrics( |
| UMA_HISTOGRAM_SPARSE_SLOWLY(raw_data_histogram, |
| (predicted_type << 16) | actual_type); |
| + form_interactions_ukm_logger->LogFieldType( |
| + form.form_signature(), field.GetFieldSignature(), prediction_source, |
| + metric_type, predicted_type, actual_type); |
| + |
| // NO_SERVER_DATA is the equivalent of predicting UNKNOWN. |
| if (predicted_type == NO_SERVER_DATA) |
| predicted_type = UNKNOWN_TYPE; |
| @@ -664,27 +707,35 @@ void AutofillMetrics::LogDeveloperEngagementMetric( |
| } |
| void AutofillMetrics::LogHeuristicPredictionQualityMetrics( |
| - const ServerFieldTypeSet& possible_types, |
| - ServerFieldType predicted_type, |
| - AutofillMetrics::QualityMetricType metric_type) { |
| - LogPredictionQualityMetrics("Heuristic", possible_types, predicted_type, |
| - metric_type); |
| + FormInteractionsUkmLogger* form_interactions_ukm_logger, |
| + const FormStructure& form, |
| + const AutofillField& field, |
| + QualityMetricType metric_type) { |
| + LogPredictionQualityMetrics( |
| + PREDICTION_SOURCE_HEURISTIC, |
| + AutofillType(field.heuristic_type()).GetStorableType(), |
| + form_interactions_ukm_logger, form, field, metric_type); |
| } |
| void AutofillMetrics::LogServerPredictionQualityMetrics( |
| - const ServerFieldTypeSet& possible_types, |
| - ServerFieldType predicted_type, |
| - AutofillMetrics::QualityMetricType metric_type) { |
| - LogPredictionQualityMetrics("Server", possible_types, predicted_type, |
| - metric_type); |
| + FormInteractionsUkmLogger* form_interactions_ukm_logger, |
| + const FormStructure& form, |
| + const AutofillField& field, |
| + QualityMetricType metric_type) { |
| + LogPredictionQualityMetrics( |
| + PREDICTION_SOURCE_SERVER, |
| + AutofillType(field.server_type()).GetStorableType(), |
| + form_interactions_ukm_logger, form, field, metric_type); |
| } |
| void AutofillMetrics::LogOverallPredictionQualityMetrics( |
| - const ServerFieldTypeSet& possible_types, |
| - ServerFieldType predicted_type, |
| - AutofillMetrics::QualityMetricType metric_type) { |
| - LogPredictionQualityMetrics("Overall", possible_types, predicted_type, |
| - metric_type); |
| + FormInteractionsUkmLogger* form_interactions_ukm_logger, |
| + const FormStructure& form, |
| + const AutofillField& field, |
| + QualityMetricType metric_type) { |
| + LogPredictionQualityMetrics( |
| + PREDICTION_SOURCE_OVERALL, field.Type().GetStorableType(), |
| + form_interactions_ukm_logger, form, field, metric_type); |
| } |
| // static |
| @@ -1324,6 +1375,65 @@ void AutofillMetrics::FormInteractionsUkmLogger::LogTextFieldDidChange( |
| MillisecondsSinceFormParsed()); |
| } |
| +void AutofillMetrics::FormInteractionsUkmLogger::LogFieldFillStatus( |
| + const FormStructure& form, |
| + const AutofillField& field, |
| + QualityMetricType metric_type) { |
| + if (!CanLog()) |
| + return; |
| + |
| + if (source_id_ == -1) |
| + GetNewSourceID(); |
| + |
| + std::unique_ptr<ukm::UkmEntryBuilder> builder = |
| + ukm_recorder_->GetEntryBuilder(source_id_, |
| + internal::kUKMFieldFillStatusEntryName); |
| + builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName, |
| + MillisecondsSinceFormParsed()); |
| + builder->AddMetric(internal::kUKMFormSignatureMetricName, |
| + static_cast<int64_t>(form.form_signature())); |
| + builder->AddMetric(internal::kUKMFieldSignatureMetricName, |
| + static_cast<int64_t>(field.GetFieldSignature())); |
| + builder->AddMetric(internal::kUKMValidationEventMetricName, |
| + static_cast<int64_t>(metric_type)); |
| + builder->AddMetric(internal::kUKMIsAutofilledMetricName, |
| + static_cast<int64_t>(field.is_autofilled)); |
| + builder->AddMetric(internal::kUKMWasPreviouslyAutofilledMetricName, |
| + static_cast<int64_t>(field.previously_autofilled())); |
| +} |
| + |
| +void AutofillMetrics::FormInteractionsUkmLogger::LogFieldType( |
| + FormSignature form_signature, |
| + FieldSignature field_signature, |
| + QualityMetricPredictionSource prediction_source, |
| + QualityMetricType metric_type, |
| + ServerFieldType predicted_type, |
| + ServerFieldType actual_type) { |
| + if (!CanLog()) |
| + return; |
| + |
| + if (source_id_ == -1) |
| + GetNewSourceID(); |
| + |
| + std::unique_ptr<ukm::UkmEntryBuilder> builder = |
| + ukm_recorder_->GetEntryBuilder(source_id_, |
| + internal::kUKMFieldTypeEntryName); |
| + builder->AddMetric(internal::kUKMMillisecondsSinceFormParsedMetricName, |
| + MillisecondsSinceFormParsed()); |
| + builder->AddMetric(internal::kUKMFormSignatureMetricName, |
| + static_cast<int64_t>(form_signature)); |
| + builder->AddMetric(internal::kUKMFieldSignatureMetricName, |
| + static_cast<int64_t>(field_signature)); |
| + builder->AddMetric(internal::kUKMValidationEventMetricName, |
| + static_cast<int64_t>(metric_type)); |
| + builder->AddMetric(internal::kUKMPredictionSourceMetricName, |
| + static_cast<int64_t>(prediction_source)); |
| + builder->AddMetric(internal::kUKMPredictedTypeMetricName, |
| + static_cast<int64_t>(predicted_type)); |
| + builder->AddMetric(internal::kUKMActualTypeMetricName, |
| + static_cast<int64_t>(actual_type)); |
| +} |
| + |
| void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted( |
| AutofillFormSubmittedState state) { |
| if (!CanLog()) |
| @@ -1361,7 +1471,10 @@ int64_t |
| AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormParsed() |
| const { |
| DCHECK(!form_parsed_timestamp_.is_null()); |
| - return (base::TimeTicks::Now() - form_parsed_timestamp_).InMilliseconds(); |
| + // Use the pinned timestamp as the current time if it's set. |
| + base::TimeTicks now = |
| + pinned_timestamp_.is_null() ? base::TimeTicks::Now() : pinned_timestamp_; |
|
Mathieu
2017/06/27 21:02:27
AutofillClock::Now would remove the need for pinne
Roger McFarlane (Chromium)
2017/06/28 17:41:01
No, pinned timestamp is to give all events generat
|
| + return (now - form_parsed_timestamp_).InMilliseconds(); |
| } |
| void AutofillMetrics::FormInteractionsUkmLogger::GetNewSourceID() { |