| 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 e813b1836f15f987cf2b02cadc879399f5e49b74..77442395f201073a68feac7dc21890f545343393 100644
|
| --- a/components/autofill/core/browser/autofill_metrics.cc
|
| +++ b/components/autofill/core/browser/autofill_metrics.cc
|
| @@ -5,6 +5,8 @@
|
| #include "components/autofill/core/browser/autofill_metrics.h"
|
|
|
| #include <algorithm>
|
| +#include <utility>
|
| +#include <vector>
|
|
|
| #include "base/logging.h"
|
| #include "base/metrics/histogram_macros.h"
|
| @@ -12,6 +14,7 @@
|
| #include "base/metrics/user_metrics.h"
|
| #include "base/time/time.h"
|
| #include "components/autofill/core/browser/autofill_experiments.h"
|
| +#include "components/autofill/core/browser/autofill_field.h"
|
| #include "components/autofill/core/browser/autofill_type.h"
|
| #include "components/autofill/core/browser/form_structure.h"
|
| #include "components/autofill/core/common/form_data.h"
|
| @@ -22,6 +25,28 @@ const char kUKMCardUploadDecisionEntryName[] = "Autofill.CardUploadDecision";
|
| const char kUKMCardUploadDecisionMetricName[] = "UploadDecision";
|
| const char kUKMDeveloperEngagementEntryName[] = "Autofill.DeveloperEngagement";
|
| const char kUKMDeveloperEngagementMetricName[] = "DeveloperEngagement";
|
| +const char kUKMMillisecondsSinceFormLoadedMetricName[] =
|
| + "MillisecondsSinceFormLoaded";
|
| +const char kUKMInteractedWithFormEntryName[] = "Autofill.InteractedWithForm";
|
| +const char kUKMIsForCreditCardMetricName[] = "IsForCreditCard";
|
| +const char kUKMLocalRecordTypeCountMetricName[] = "LocalRecordTypeCount";
|
| +const char kUKMServerRecordTypeCountMetricName[] = "ServerRecordTypeCount";
|
| +const char kUKMSuggestionsShownEntryName[] = "Autofill.SuggestionsShown";
|
| +const char kUKMSelectedMaskedServerCardEntryName[] =
|
| + "Autofill.SelectedMaskedServerCard";
|
| +const char kUKMSuggestionFilledEntryName[] = "Autofill.SuggestionFilled";
|
| +const char kUKMRecordTypeMetricName[] = "RecordType";
|
| +const char kUKMTextFieldDidChangeEntryName[] = "Autofill.TextFieldDidChange";
|
| +const char kUKMFieldTypeGroupMetricName[] = "FieldTypeGroup";
|
| +const char kUKMHeuristicTypeMetricName[] = "HeuristicType";
|
| +const char kUKMServerTypeMetricName[] = "ServerType";
|
| +const char kUKMHtmlFieldTypeMetricName[] = "HtmlFieldType";
|
| +const char kUKMHtmlFieldModeMetricName[] = "HtmlFieldMode";
|
| +const char kUKMIsAutofilledMetricName[] = "IsAutofilled";
|
| +const char kUKMIsEmptyMetricName[] = "IsEmpty";
|
| +const char kUKMFormSubmittedEntryName[] = "Autofill.AutofillFormSubmitted";
|
| +const char kUKMAutofillFormSubmittedStateMetricName[] =
|
| + "AutofillFormSubmittedState";
|
| } // namespace internal
|
|
|
| namespace autofill {
|
| @@ -616,7 +641,8 @@ void AutofillMetrics::LogProfileActionOnFormSubmitted(
|
|
|
| // static
|
| void AutofillMetrics::LogAutofillFormSubmittedState(
|
| - AutofillFormSubmittedState state) {
|
| + AutofillFormSubmittedState state,
|
| + AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger) {
|
| UMA_HISTOGRAM_ENUMERATION("Autofill.FormSubmittedState", state,
|
| AUTOFILL_FORM_SUBMITTED_STATE_ENUM_SIZE);
|
|
|
| @@ -650,6 +676,7 @@ void AutofillMetrics::LogAutofillFormSubmittedState(
|
| NOTREACHED();
|
| break;
|
| }
|
| + form_interactions_ukm_logger->LogFormSubmitted(state);
|
| }
|
|
|
| // static
|
| @@ -706,7 +733,7 @@ void AutofillMetrics::LogCardUploadDecisionUkm(
|
| if (upload_decision >= AutofillMetrics::NUM_CARD_UPLOAD_DECISION_METRICS)
|
| return;
|
|
|
| - const std::map<std::string, int> metrics = {
|
| + const std::vector<std::pair<const char*, int>> metrics = {
|
| {internal::kUKMCardUploadDecisionMetricName,
|
| static_cast<int>(upload_decision)}};
|
| LogUkm(ukm_service, url, internal::kUKMCardUploadDecisionEntryName, metrics);
|
| @@ -716,18 +743,22 @@ void AutofillMetrics::LogCardUploadDecisionUkm(
|
| void AutofillMetrics::LogDeveloperEngagementUkm(
|
| ukm::UkmService* ukm_service,
|
| const GURL& url,
|
| - AutofillMetrics::DeveloperEngagementMetric metric) {
|
| - const std::map<std::string, int> form_structure_metrics = {
|
| - {internal::kUKMDeveloperEngagementMetricName, static_cast<int>(metric)}};
|
| + std::vector<AutofillMetrics::DeveloperEngagementMetric> metrics) {
|
| + std::vector<std::pair<const char*, int>> form_structure_metrics;
|
| + for (const auto it : metrics)
|
| + form_structure_metrics.push_back(
|
| + {internal::kUKMDeveloperEngagementMetricName, static_cast<int>(it)});
|
| +
|
| LogUkm(ukm_service, url, internal::kUKMDeveloperEngagementEntryName,
|
| form_structure_metrics);
|
| }
|
|
|
| // static
|
| -bool AutofillMetrics::LogUkm(ukm::UkmService* ukm_service,
|
| - const GURL& url,
|
| - const std::string& ukm_entry_name,
|
| - const std::map<std::string, int>& metrics) {
|
| +bool AutofillMetrics::LogUkm(
|
| + ukm::UkmService* ukm_service,
|
| + const GURL& url,
|
| + const std::string& ukm_entry_name,
|
| + const std::vector<std::pair<const char*, int>>& metrics) {
|
| if (!IsUkmLoggingEnabled() || !ukm_service || !url.is_valid() ||
|
| metrics.empty()) {
|
| return false;
|
| @@ -739,16 +770,18 @@ bool AutofillMetrics::LogUkm(ukm::UkmService* ukm_service,
|
| ukm_service->GetEntryBuilder(source_id, ukm_entry_name.c_str());
|
|
|
| for (auto it = metrics.begin(); it != metrics.end(); ++it) {
|
| - builder->AddMetric(it->first.c_str(), it->second);
|
| + builder->AddMetric(it->first, it->second);
|
| }
|
|
|
| return true;
|
| }
|
|
|
| -AutofillMetrics::FormEventLogger::FormEventLogger(bool is_for_credit_card)
|
| +AutofillMetrics::FormEventLogger::FormEventLogger(
|
| + bool is_for_credit_card,
|
| + AutofillMetrics::FormInteractionsUkmLogger* form_interactions_ukm_logger)
|
| : is_for_credit_card_(is_for_credit_card),
|
| - is_server_data_available_(false),
|
| - is_local_data_available_(false),
|
| + server_record_type_count_(0),
|
| + local_record_type_count_(0),
|
| is_context_secure_(false),
|
| has_logged_interacted_(false),
|
| has_logged_suggestions_shown_(false),
|
| @@ -757,11 +790,15 @@ AutofillMetrics::FormEventLogger::FormEventLogger(bool is_for_credit_card)
|
| has_logged_will_submit_(false),
|
| has_logged_submitted_(false),
|
| logged_suggestion_filled_was_server_data_(false),
|
| - logged_suggestion_filled_was_masked_server_card_(false) {}
|
| + logged_suggestion_filled_was_masked_server_card_(false),
|
| + form_interactions_ukm_logger_(form_interactions_ukm_logger) {}
|
|
|
| void AutofillMetrics::FormEventLogger::OnDidInteractWithAutofillableForm() {
|
| if (!has_logged_interacted_) {
|
| has_logged_interacted_ = true;
|
| + form_interactions_ukm_logger_->LogInteractedWithForm(
|
| + is_for_credit_card_, local_record_type_count_,
|
| + server_record_type_count_);
|
| Log(AutofillMetrics::FORM_EVENT_INTERACTED_ONCE);
|
| }
|
| }
|
| @@ -786,6 +823,8 @@ void AutofillMetrics::FormEventLogger::OnDidPollSuggestions(
|
| }
|
|
|
| void AutofillMetrics::FormEventLogger::OnDidShowSuggestions() {
|
| + form_interactions_ukm_logger_->LogSuggestionsShown();
|
| +
|
| Log(AutofillMetrics::FORM_EVENT_SUGGESTIONS_SHOWN);
|
| if (!has_logged_suggestions_shown_) {
|
| has_logged_suggestions_shown_ = true;
|
| @@ -803,17 +842,22 @@ void AutofillMetrics::FormEventLogger::OnDidShowSuggestions() {
|
|
|
| void AutofillMetrics::FormEventLogger::OnDidSelectMaskedServerCardSuggestion() {
|
| DCHECK(is_for_credit_card_);
|
| + form_interactions_ukm_logger_->LogSelectedMaskedServerCard();
|
| +
|
| Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED);
|
| if (!has_logged_masked_server_card_suggestion_selected_) {
|
| has_logged_masked_server_card_suggestion_selected_ = true;
|
| - Log(AutofillMetrics
|
| - ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE);
|
| + Log(AutofillMetrics::
|
| + FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SELECTED_ONCE);
|
| }
|
| }
|
|
|
| void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
|
| const CreditCard& credit_card) {
|
| DCHECK(is_for_credit_card_);
|
| + form_interactions_ukm_logger_->LogDidFillSuggestion(
|
| + static_cast<int>(credit_card.record_type()));
|
| +
|
| if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD)
|
| Log(AutofillMetrics::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED);
|
| else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD)
|
| @@ -829,8 +873,8 @@ void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
|
| logged_suggestion_filled_was_masked_server_card_ =
|
| credit_card.record_type() == CreditCard::MASKED_SERVER_CARD;
|
| if (credit_card.record_type() == CreditCard::MASKED_SERVER_CARD) {
|
| - Log(AutofillMetrics
|
| - ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE);
|
| + Log(AutofillMetrics::
|
| + FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_FILLED_ONCE);
|
| } else if (credit_card.record_type() == CreditCard::FULL_SERVER_CARD) {
|
| Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE);
|
| } else {
|
| @@ -845,6 +889,9 @@ void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
|
| void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
|
| const AutofillProfile& profile) {
|
| DCHECK(!is_for_credit_card_);
|
| + form_interactions_ukm_logger_->LogDidFillSuggestion(
|
| + static_cast<int>(profile.record_type()));
|
| +
|
| if (profile.record_type() == AutofillProfile::SERVER_PROFILE)
|
| Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED);
|
| else
|
| @@ -855,8 +902,8 @@ void AutofillMetrics::FormEventLogger::OnDidFillSuggestion(
|
| logged_suggestion_filled_was_server_data_ =
|
| profile.record_type() == AutofillProfile::SERVER_PROFILE;
|
| Log(profile.record_type() == AutofillProfile::SERVER_PROFILE
|
| - ? AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
|
| - : AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
|
| + ? AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_FILLED_ONCE
|
| + : AutofillMetrics::FORM_EVENT_LOCAL_SUGGESTION_FILLED_ONCE);
|
| }
|
|
|
| base::RecordAction(
|
| @@ -904,8 +951,8 @@ void AutofillMetrics::FormEventLogger::OnFormSubmitted() {
|
| if (!has_logged_suggestion_filled_) {
|
| Log(AutofillMetrics::FORM_EVENT_NO_SUGGESTION_SUBMITTED_ONCE);
|
| } else if (logged_suggestion_filled_was_masked_server_card_) {
|
| - Log(AutofillMetrics
|
| - ::FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE);
|
| + Log(AutofillMetrics::
|
| + FORM_EVENT_MASKED_SERVER_CARD_SUGGESTION_SUBMITTED_ONCE);
|
| } else if (logged_suggestion_filled_was_server_data_) {
|
| Log(AutofillMetrics::FORM_EVENT_SERVER_SUGGESTION_SUBMITTED_ONCE);
|
| } else {
|
| @@ -937,15 +984,154 @@ void AutofillMetrics::FormEventLogger::Log(FormEvent event) const {
|
| // Logging again in a different histogram for segmentation purposes.
|
| // TODO(waltercacau): Re-evaluate if we still need such fine grained
|
| // segmentation. http://crbug.com/454018
|
| - if (!is_server_data_available_ && !is_local_data_available_)
|
| + if (server_record_type_count_ == 0 && local_record_type_count_ == 0)
|
| name += ".WithNoData";
|
| - else if (is_server_data_available_ && !is_local_data_available_)
|
| + else if (server_record_type_count_ > 0 && local_record_type_count_ == 0)
|
| name += ".WithOnlyServerData";
|
| - else if (!is_server_data_available_ && is_local_data_available_)
|
| + else if (server_record_type_count_ == 0 && local_record_type_count_ > 0)
|
| name += ".WithOnlyLocalData";
|
| else
|
| name += ".WithBothServerAndLocalData";
|
| LogUMAHistogramEnumeration(name, event, NUM_FORM_EVENTS);
|
| }
|
|
|
| +AutofillMetrics::FormInteractionsUkmLogger::FormInteractionsUkmLogger(
|
| + ukm::UkmService* ukm_service)
|
| + : ukm_service_(ukm_service) {}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::OnFormsLoaded(
|
| + const GURL& url) {
|
| + if (!IsUkmLoggingEnabled() || ukm_service_ == nullptr)
|
| + return;
|
| +
|
| + url_ = url;
|
| + form_loaded_timestamp_ = base::TimeTicks::Now();
|
| +}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::LogInteractedWithForm(
|
| + bool is_for_credit_card,
|
| + size_t local_record_type_count,
|
| + size_t server_record_type_count) {
|
| + if (!CanLog())
|
| + return;
|
| +
|
| + if (source_id_ == -1)
|
| + GetNewSourceID();
|
| +
|
| + std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
|
| + source_id_, internal::kUKMInteractedWithFormEntryName);
|
| + builder->AddMetric(internal::kUKMIsForCreditCardMetricName,
|
| + is_for_credit_card);
|
| + builder->AddMetric(internal::kUKMLocalRecordTypeCountMetricName,
|
| + local_record_type_count);
|
| + builder->AddMetric(internal::kUKMServerRecordTypeCountMetricName,
|
| + server_record_type_count);
|
| +}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::LogSuggestionsShown() {
|
| + if (!CanLog())
|
| + return;
|
| +
|
| + if (source_id_ == -1)
|
| + GetNewSourceID();
|
| +
|
| + std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
|
| + source_id_, internal::kUKMSuggestionsShownEntryName);
|
| + builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
|
| + MillisecondsSinceFormLoaded());
|
| +}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::LogSelectedMaskedServerCard() {
|
| + if (!CanLog())
|
| + return;
|
| +
|
| + if (source_id_ == -1)
|
| + GetNewSourceID();
|
| +
|
| + std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
|
| + source_id_, internal::kUKMSelectedMaskedServerCardEntryName);
|
| + builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
|
| + MillisecondsSinceFormLoaded());
|
| +}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::LogDidFillSuggestion(
|
| + int record_type) {
|
| + if (!CanLog())
|
| + return;
|
| +
|
| + if (source_id_ == -1)
|
| + GetNewSourceID();
|
| +
|
| + std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
|
| + source_id_, internal::kUKMSuggestionFilledEntryName);
|
| + builder->AddMetric(internal::kUKMRecordTypeMetricName, record_type);
|
| + builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
|
| + MillisecondsSinceFormLoaded());
|
| +}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::LogTextFieldDidChange(
|
| + const AutofillField& field) {
|
| + if (!CanLog())
|
| + return;
|
| +
|
| + if (source_id_ == -1)
|
| + GetNewSourceID();
|
| +
|
| + std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
|
| + source_id_, internal::kUKMTextFieldDidChangeEntryName);
|
| + builder->AddMetric(internal::kUKMFieldTypeGroupMetricName,
|
| + static_cast<int>(field.Type().group()));
|
| + builder->AddMetric(internal::kUKMHeuristicTypeMetricName,
|
| + static_cast<int>(field.heuristic_type()));
|
| + builder->AddMetric(internal::kUKMServerTypeMetricName,
|
| + static_cast<int>(field.server_type()));
|
| + builder->AddMetric(internal::kUKMHtmlFieldTypeMetricName,
|
| + static_cast<int>(field.html_type()));
|
| + builder->AddMetric(internal::kUKMHtmlFieldModeMetricName,
|
| + static_cast<int>(field.html_mode()));
|
| + builder->AddMetric(internal::kUKMIsAutofilledMetricName, field.is_autofilled);
|
| + builder->AddMetric(internal::kUKMIsEmptyMetricName, field.IsEmpty());
|
| + builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
|
| + MillisecondsSinceFormLoaded());
|
| +}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::LogFormSubmitted(
|
| + AutofillFormSubmittedState state) {
|
| + if (!CanLog())
|
| + return;
|
| +
|
| + if (source_id_ == -1)
|
| + GetNewSourceID();
|
| +
|
| + std::unique_ptr<ukm::UkmEntryBuilder> builder = ukm_service_->GetEntryBuilder(
|
| + source_id_, internal::kUKMFormSubmittedEntryName);
|
| + builder->AddMetric(internal::kUKMAutofillFormSubmittedStateMetricName,
|
| + static_cast<int>(state));
|
| + builder->AddMetric(internal::kUKMMillisecondsSinceFormLoadedMetricName,
|
| + MillisecondsSinceFormLoaded());
|
| +}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::UpdateSourceURL(
|
| + const GURL& url) {
|
| + url_ = url;
|
| + if (CanLog())
|
| + ukm_service_->UpdateSourceURL(source_id_, url_);
|
| +}
|
| +
|
| +bool AutofillMetrics::FormInteractionsUkmLogger::CanLog() const {
|
| + return IsUkmLoggingEnabled() && ukm_service_ && url_.is_valid();
|
| +}
|
| +
|
| +int64_t
|
| +AutofillMetrics::FormInteractionsUkmLogger::MillisecondsSinceFormLoaded()
|
| + const {
|
| + DCHECK(!form_loaded_timestamp_.is_null());
|
| + return (base::TimeTicks::Now() - form_loaded_timestamp_).InMilliseconds();
|
| +}
|
| +
|
| +void AutofillMetrics::FormInteractionsUkmLogger::GetNewSourceID() {
|
| + source_id_ = ukm_service_->GetNewSourceID();
|
| + ukm_service_->UpdateSourceURL(source_id_, url_);
|
| +}
|
| +
|
| } // namespace autofill
|
|
|