diff options
author | mathp <mathp@chromium.org> | 2015-03-17 17:16:16 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-18 00:17:22 +0000 |
commit | 94e3f0b1ec9dab48251c7322c1a3252bb7a5a8c6 (patch) | |
tree | 51f9d9b891d9d1531d909e59371cd51b8596ba57 | |
parent | d0e32d4246d27108922fdd2abbafa7cbcd182763 (diff) | |
download | chromium_src-94e3f0b1ec9dab48251c7322c1a3252bb7a5a8c6.zip chromium_src-94e3f0b1ec9dab48251c7322c1a3252bb7a5a8c6.tar.gz chromium_src-94e3f0b1ec9dab48251c7322c1a3252bb7a5a8c6.tar.bz2 |
[Autofill] Add infrastructure for Rappor metrics, and log 2 metrics.
Will use Rappor to log the domains where an Autofillable form is submitted and contained a high number of autofill prediction mismatches.
BUG=465793
TEST=AutofillMetricsTest -- components_unittests
TBR=asvitkine
Review URL: https://codereview.chromium.org/998073002
Cr-Commit-Position: refs/heads/master@{#321027}
-rw-r--r-- | android_webview/native/aw_autofill_client.cc | 4 | ||||
-rw-r--r-- | android_webview/native/aw_autofill_client.h | 1 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/chrome_autofill_client.cc | 5 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/chrome_autofill_client.h | 1 | ||||
-rw-r--r-- | components/autofill.gypi | 2 | ||||
-rw-r--r-- | components/autofill/core/DEPS | 1 | ||||
-rw-r--r-- | components/autofill/core/browser/BUILD.gn | 2 | ||||
-rw-r--r-- | components/autofill/core/browser/autofill_client.h | 7 | ||||
-rw-r--r-- | components/autofill/core/browser/autofill_manager.cc | 3 | ||||
-rw-r--r-- | components/autofill/core/browser/autofill_metrics_unittest.cc | 194 | ||||
-rw-r--r-- | components/autofill/core/browser/form_structure.cc | 26 | ||||
-rw-r--r-- | components/autofill/core/browser/form_structure.h | 7 | ||||
-rw-r--r-- | components/autofill/core/browser/test_autofill_client.cc | 7 | ||||
-rw-r--r-- | components/autofill/core/browser/test_autofill_client.h | 7 | ||||
-rw-r--r-- | tools/metrics/rappor/rappor.xml | 18 |
15 files changed, 280 insertions, 5 deletions
diff --git a/android_webview/native/aw_autofill_client.cc b/android_webview/native/aw_autofill_client.cc index b9210e5..471576c 100644 --- a/android_webview/native/aw_autofill_client.cc +++ b/android_webview/native/aw_autofill_client.cc @@ -70,6 +70,10 @@ IdentityProvider* AwAutofillClient::GetIdentityProvider() { return nullptr; } +rappor::RapporService* AwAutofillClient::GetRapporService() { + return nullptr; +} + autofill::PersonalDataManager* AwAutofillClient::GetPersonalDataManager() { return nullptr; } diff --git a/android_webview/native/aw_autofill_client.h b/android_webview/native/aw_autofill_client.h index d8e4651..96405fc 100644 --- a/android_webview/native/aw_autofill_client.h +++ b/android_webview/native/aw_autofill_client.h @@ -60,6 +60,7 @@ class AwAutofillClient : public autofill::AutofillClient, scoped_refptr<autofill::AutofillWebDataService> GetDatabase() override; PrefService* GetPrefs() override; IdentityProvider* GetIdentityProvider() override; + rappor::RapporService* GetRapporService() override; void HideRequestAutocompleteDialog() override; void ShowAutofillSettings() override; void ShowUnmaskPrompt( diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc index 23983d9..173f3bf 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.cc +++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/prefs/pref_service.h" #include "chrome/browser/autofill/personal_data_manager_factory.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/infobars/infobar_service.h" #include "chrome/browser/password_manager/chrome_password_manager_client.h" #include "chrome/browser/profiles/profile.h" @@ -120,6 +121,10 @@ IdentityProvider* ChromeAutofillClient::GetIdentityProvider() { return identity_provider_.get(); } +rappor::RapporService* ChromeAutofillClient::GetRapporService() { + return g_browser_process->rappor_service(); +} + void ChromeAutofillClient::ShowAutofillSettings() { #if defined(OS_ANDROID) chrome::android::ChromiumApplication::ShowAutofillSettings(); diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h index 1ce82b7..7065407 100644 --- a/chrome/browser/ui/autofill/chrome_autofill_client.h +++ b/chrome/browser/ui/autofill/chrome_autofill_client.h @@ -47,6 +47,7 @@ class ChromeAutofillClient scoped_refptr<AutofillWebDataService> GetDatabase() override; PrefService* GetPrefs() override; IdentityProvider* GetIdentityProvider() override; + rappor::RapporService* GetRapporService() override; void HideRequestAutocompleteDialog() override; void ShowAutofillSettings() override; void ShowUnmaskPrompt(const CreditCard& card, diff --git a/components/autofill.gypi b/components/autofill.gypi index 9104b45..493438f 100644 --- a/components/autofill.gypi +++ b/components/autofill.gypi @@ -101,6 +101,7 @@ 'keyed_service_core', 'os_crypt', 'pref_registry', + 'rappor', 'signin_core_common', 'webdata_common', ], @@ -272,6 +273,7 @@ 'autofill_core_browser', 'os_crypt', 'pref_registry', + 'rappor', ], 'sources': [ 'autofill/core/browser/autofill_test_utils.cc', diff --git a/components/autofill/core/DEPS b/components/autofill/core/DEPS index fb45023..2ee4fb8 100644 --- a/components/autofill/core/DEPS +++ b/components/autofill/core/DEPS @@ -1,4 +1,5 @@ include_rules = [ "+components/os_crypt", "+components/pref_registry", + "+components/rappor", ] diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 7c6d06b..c837bf8 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn @@ -226,6 +226,7 @@ static_library("test_support") { "//components/autofill/core/common", "//components/os_crypt", "//components/pref_registry", + "//components/rappor", "//skia", "//testing/gtest", ] @@ -275,6 +276,7 @@ source_set("unit_tests") { "//base/test:test_support", "//components/autofill/core/common", "//components/os_crypt", + "//components/rappor:test_support", "//components/resources", "//components/strings", "//components/webdata/common", diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h index ef3039b..d5f8d96 100644 --- a/components/autofill/core/browser/autofill_client.h +++ b/components/autofill/core/browser/autofill_client.h @@ -24,6 +24,10 @@ class Rect; class RectF; } +namespace rappor { +class RapporService; +} + class GURL; class PrefService; @@ -92,6 +96,9 @@ class AutofillClient { // Gets the IdentityProvider associated with the client (for OAuth2). virtual IdentityProvider* GetIdentityProvider() = 0; + // Gets the RapporService associated with the client (for metrics). + virtual rappor::RapporService* GetRapporService() = 0; + // Hides the associated request autocomplete dialog (if it exists). virtual void HideRequestAutocompleteDialog() = 0; diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc index 98aabf7..0ccf7d9 100644 --- a/components/autofill/core/browser/autofill_manager.cc +++ b/components/autofill/core/browser/autofill_manager.cc @@ -811,7 +811,8 @@ void AutofillManager::UploadFormDataAsyncCallback( const TimeTicks& interaction_time, const TimeTicks& submission_time) { submitted_form->LogQualityMetrics(load_time, interaction_time, - submission_time); + submission_time, + client_->GetRapporService()); if (submitted_form->ShouldBeCrowdsourced()) UploadFormData(*submitted_form); diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc index 409e9bd..973a6d5 100644 --- a/components/autofill/core/browser/autofill_metrics_unittest.cc +++ b/components/autofill/core/browser/autofill_metrics_unittest.cc @@ -24,6 +24,7 @@ #include "components/autofill/core/common/autofill_pref_names.h" #include "components/autofill/core/common/form_data.h" #include "components/autofill/core/common/form_field_data.h" +#include "components/rappor/test_rappor_service.h" #include "components/signin/core/common/signin_pref_names.h" #include "components/webdata/common/web_data_results.h" #include "testing/gtest/include/gtest/gtest.h" @@ -461,6 +462,199 @@ TEST_F(AutofillMetricsTest, QualityMetrics) { GetFieldTypeGroupMetric(NAME_FULL, AutofillMetrics::TYPE_MISMATCH), 1); } +// Test that we do not log RAPPOR metrics when the number of mismatches is not +// high enough. +TEST_F(AutofillMetricsTest, Rappor_LowMismatchRate_NoMetricsReported) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.user_submitted = true; + + std::vector<ServerFieldType> heuristic_types, server_types; + FormFieldData field; + + test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", + "text", &field); + field.is_autofilled = true; + form.fields.push_back(field); + heuristic_types.push_back(NAME_FULL); + server_types.push_back(NAME_FULL); + + test::CreateTestFormField("Autofill Failed", "autofillfailed", + "buddy@gmail.com", "text", &field); + field.is_autofilled = false; + form.fields.push_back(field); + heuristic_types.push_back(EMAIL_ADDRESS); + server_types.push_back(NAME_LAST); + + test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); + field.is_autofilled = true; + form.fields.push_back(field); + heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); + server_types.push_back(EMAIL_ADDRESS); + + // Simulate having seen this form on page load. + autofill_manager_->AddSeenForm(form, heuristic_types, server_types); + + // Simulate form submission. + autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); + + // The number of mismatches did not trigger the RAPPOR metric logging. + EXPECT_EQ(0, autofill_client_.test_rappor_service()->GetReportsCount()); +} + +// Test that we don't log RAPPOR metrics in the case heuristics and/or server +// have no data. +TEST_F(AutofillMetricsTest, Rappor_NoDataServerAndHeuristic_NoMetricsReported) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.user_submitted = true; + + std::vector<ServerFieldType> heuristic_types, server_types; + FormFieldData field; + + test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", + "text", &field); + field.is_autofilled = true; + form.fields.push_back(field); + heuristic_types.push_back(UNKNOWN_TYPE); + server_types.push_back(NO_SERVER_DATA); + + test::CreateTestFormField("Autofill Failed", "autofillfailed", + "buddy@gmail.com", "text", &field); + field.is_autofilled = false; + form.fields.push_back(field); + heuristic_types.push_back(UNKNOWN_TYPE); + server_types.push_back(NO_SERVER_DATA); + + test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); + field.is_autofilled = true; + form.fields.push_back(field); + heuristic_types.push_back(UNKNOWN_TYPE); + server_types.push_back(NO_SERVER_DATA); + + // Simulate having seen this form on page load. + autofill_manager_->AddSeenForm(form, heuristic_types, server_types); + + // Simulate form submission. + autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); + + // No RAPPOR metrics are logged in the case of multiple UNKNOWN_TYPE and + // NO_SERVER_DATA for heuristics and server predictions, respectively. + EXPECT_EQ(0, autofill_client_.test_rappor_service()->GetReportsCount()); +} + +// Test that we log high number of mismatches for the server prediction. +TEST_F(AutofillMetricsTest, Rappor_HighServerMismatchRate_MetricsReported) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.user_submitted = true; + + std::vector<ServerFieldType> heuristic_types, server_types; + FormFieldData field; + + test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", + "text", &field); + field.is_autofilled = true; + form.fields.push_back(field); + heuristic_types.push_back(NAME_FULL); + server_types.push_back(NAME_FIRST); + + test::CreateTestFormField("Autofill Failed", "autofillfailed", + "buddy@gmail.com", "text", &field); + field.is_autofilled = false; + form.fields.push_back(field); + heuristic_types.push_back(PHONE_HOME_NUMBER); + server_types.push_back(NAME_LAST); + + test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); + field.is_autofilled = true; + form.fields.push_back(field); + heuristic_types.push_back(PHONE_HOME_CITY_AND_NUMBER); + server_types.push_back(EMAIL_ADDRESS); + + // Simulate having seen this form on page load. + autofill_manager_->AddSeenForm(form, heuristic_types, server_types); + + // Simulate form submission. + autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); + + // The number of mismatches did trigger the RAPPOR metric logging for server + // predictions. + EXPECT_EQ(1, autofill_client_.test_rappor_service()->GetReportsCount()); + std::string sample; + rappor::RapporType type; + EXPECT_FALSE( + autofill_client_.test_rappor_service()->GetRecordedSampleForMetric( + "Autofill.HighNumberOfHeuristicMismatches", &sample, &type)); + EXPECT_TRUE( + autofill_client_.test_rappor_service()->GetRecordedSampleForMetric( + "Autofill.HighNumberOfServerMismatches", &sample, &type)); + EXPECT_EQ("example.com", sample); + EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type); +} + +// Test that we log high number of mismatches for the heuristic predictions. +TEST_F(AutofillMetricsTest, Rappor_HighHeuristicMismatchRate_MetricsReported) { + // Set up our form data. + FormData form; + form.name = ASCIIToUTF16("TestForm"); + form.origin = GURL("http://example.com/form.html"); + form.action = GURL("http://example.com/submit.html"); + form.user_submitted = true; + + std::vector<ServerFieldType> heuristic_types, server_types; + FormFieldData field; + + test::CreateTestFormField("Autofilled", "autofilled", "Elvis Aaron Presley", + "text", &field); + field.is_autofilled = true; + form.fields.push_back(field); + heuristic_types.push_back(NAME_FIRST); + server_types.push_back(NAME_FULL); + + test::CreateTestFormField("Autofill Failed", "autofillfailed", + "buddy@gmail.com", "text", &field); + field.is_autofilled = false; + form.fields.push_back(field); + heuristic_types.push_back(PHONE_HOME_NUMBER); + server_types.push_back(NAME_LAST); + + test::CreateTestFormField("Phone", "phone", "2345678901", "tel", &field); + field.is_autofilled = true; + form.fields.push_back(field); + heuristic_types.push_back(EMAIL_ADDRESS); + server_types.push_back(PHONE_HOME_WHOLE_NUMBER); + + // Simulate having seen this form on page load. + autofill_manager_->AddSeenForm(form, heuristic_types, server_types); + + // Simulate form submission. + autofill_manager_->WillSubmitForm(form, TimeTicks::Now()); + + // The number of mismatches did trigger the RAPPOR metric logging for + // heuristic predictions. + EXPECT_EQ(1, autofill_client_.test_rappor_service()->GetReportsCount()); + std::string sample; + rappor::RapporType type; + EXPECT_FALSE( + autofill_client_.test_rappor_service()->GetRecordedSampleForMetric( + "Autofill.HighNumberOfServerMismatches", &sample, &type)); + EXPECT_TRUE( + autofill_client_.test_rappor_service()->GetRecordedSampleForMetric( + "Autofill.HighNumberOfHeuristicMismatches", &sample, &type)); + EXPECT_EQ("example.com", sample); + EXPECT_EQ(rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, type); +} + // Verify that when a field is annotated with the autocomplete attribute, its // predicted type is remembered when quality metrics are logged. TEST_F(AutofillMetricsTest, PredictedMetricsWithAutocomplete) { diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc index 6a8ef7c..5f1522a 100644 --- a/components/autofill/core/browser/form_structure.cc +++ b/components/autofill/core/browser/form_structure.cc @@ -27,6 +27,8 @@ #include "components/autofill/core/common/form_data_predictions.h" #include "components/autofill/core/common/form_field_data.h" #include "components/autofill/core/common/form_field_data_predictions.h" +#include "components/rappor/rappor_service.h" +#include "components/rappor/rappor_utils.h" #include "third_party/icu/source/i18n/unicode/regex.h" #include "third_party/webrtc/libjingle/xmllite/xmlelement.h" @@ -54,9 +56,13 @@ const char kXMLElementForm[] = "form"; const char kBillingMode[] = "billing"; const char kShippingMode[] = "shipping"; -// Stip away >= 5 consecutive digits. +// Strip away >= 5 consecutive digits. const char kIgnorePatternInFieldName[] = "\\d{5,}+"; +// A form is considered to have a high prediction mismatch rate if the number of +// mismatches exceeds this threshold. +const int kNumberOfMismatchesThreshold = 3; + // Helper for |EncodeUploadRequest()| that creates a bit field corresponding to // |available_field_types| and returns the hex representation as a string. std::string EncodeFieldTypes(const ServerFieldTypeSet& available_field_types) { @@ -765,8 +771,11 @@ void FormStructure::UpdateFromCache(const FormStructure& cached_form) { void FormStructure::LogQualityMetrics( const base::TimeTicks& load_time, const base::TimeTicks& interaction_time, - const base::TimeTicks& submission_time) const { + const base::TimeTicks& submission_time, + rappor::RapporService* rappor_service) const { size_t num_detected_field_types = 0; + size_t num_server_mismatches = 0; + size_t num_heuristic_mismatches = 0; bool did_autofill_all_possible_fields = true; bool did_autofill_some_possible_fields = false; for (size_t i = 0; i < field_count(); ++i) { @@ -827,6 +836,7 @@ void FormStructure::LogQualityMetrics( AutofillMetrics::LogHeuristicTypePrediction(AutofillMetrics::TYPE_MATCH, field_type); } else { + ++num_heuristic_mismatches; AutofillMetrics::LogHeuristicTypePrediction( AutofillMetrics::TYPE_MISMATCH, field_type); } @@ -838,6 +848,7 @@ void FormStructure::LogQualityMetrics( AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_MATCH, field_type); } else { + ++num_server_mismatches; AutofillMetrics::LogServerTypePrediction(AutofillMetrics::TYPE_MISMATCH, field_type); } @@ -869,6 +880,17 @@ void FormStructure::LogQualityMetrics( AutofillMetrics::SUBMITTED_FILLABLE_FORM_AUTOFILLED_NONE); } + // Log some RAPPOR metrics for problematic cases. + if (num_server_mismatches >= kNumberOfMismatchesThreshold) { + rappor::SampleDomainAndRegistryFromGURL( + rappor_service, "Autofill.HighNumberOfServerMismatches", source_url_); + } + if (num_heuristic_mismatches >= kNumberOfMismatchesThreshold) { + rappor::SampleDomainAndRegistryFromGURL( + rappor_service, "Autofill.HighNumberOfHeuristicMismatches", + source_url_); + } + // Unlike the other times, the |submission_time| should always be available. DCHECK(!submission_time.is_null()); diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h index 2234719..732b607 100644 --- a/components/autofill/core/browser/form_structure.h +++ b/components/autofill/core/browser/form_structure.h @@ -34,6 +34,10 @@ namespace buzz { class XmlElement; } +namespace rappor { +class RapporService; +} + namespace autofill { struct FormData; @@ -117,7 +121,8 @@ class FormStructure { // a timestamp corresponding to the form's submission. void LogQualityMetrics(const base::TimeTicks& load_time, const base::TimeTicks& interaction_time, - const base::TimeTicks& submission_time) const; + const base::TimeTicks& submission_time, + rappor::RapporService* rappor_service) const; // Classifies each field in |fields_| based upon its |autocomplete| attribute, // if the attribute is available. The association is stored into the field's diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc index eef879d..5d9f4bf 100644 --- a/components/autofill/core/browser/test_autofill_client.cc +++ b/components/autofill/core/browser/test_autofill_client.cc @@ -10,7 +10,8 @@ namespace autofill { TestAutofillClient::TestAutofillClient() : token_service_(new FakeOAuth2TokenService()), - identity_provider_(new FakeIdentityProvider(token_service_.get())) { + identity_provider_(new FakeIdentityProvider(token_service_.get())), + rappor_service_(new rappor::TestRapporService()) { } TestAutofillClient::~TestAutofillClient() { } @@ -31,6 +32,10 @@ IdentityProvider* TestAutofillClient::GetIdentityProvider() { return identity_provider_.get(); } +rappor::RapporService* TestAutofillClient::GetRapporService() { + return rappor_service_.get(); +} + void TestAutofillClient::HideRequestAutocompleteDialog() { } diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index fcafd98..41f29f1 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h @@ -10,6 +10,7 @@ #include "base/memory/scoped_ptr.h" #include "base/prefs/pref_service.h" #include "components/autofill/core/browser/autofill_client.h" +#include "components/rappor/test_rappor_service.h" #include "google_apis/gaia/fake_identity_provider.h" #include "google_apis/gaia/fake_oauth2_token_service.h" @@ -26,6 +27,7 @@ class TestAutofillClient : public AutofillClient { scoped_refptr<AutofillWebDataService> GetDatabase() override; PrefService* GetPrefs() override; IdentityProvider* GetIdentityProvider() override; + rappor::RapporService* GetRapporService() override; void HideRequestAutocompleteDialog() override; void ShowAutofillSettings() override; void ShowUnmaskPrompt(const CreditCard& card, @@ -57,11 +59,16 @@ class TestAutofillClient : public AutofillClient { void SetPrefs(scoped_ptr<PrefService> prefs) { prefs_ = prefs.Pass(); } + rappor::TestRapporService* test_rappor_service() { + return rappor_service_.get(); + } + private: // NULL by default. scoped_ptr<PrefService> prefs_; scoped_ptr<FakeOAuth2TokenService> token_service_; scoped_ptr<FakeIdentityProvider> identity_provider_; + scoped_ptr<rappor::TestRapporService> rappor_service_; DISALLOW_COPY_AND_ASSIGN(TestAutofillClient); }; diff --git a/tools/metrics/rappor/rappor.xml b/tools/metrics/rappor/rappor.xml index a4f123f..5e3fa07 100644 --- a/tools/metrics/rappor/rappor.xml +++ b/tools/metrics/rappor/rappor.xml @@ -89,6 +89,24 @@ components/rappor/rappor_service.cc. </summary> </rappor-metric> +<rappor-metric name="Autofill.HighNumberOfHeuristicMismatches" + type="ETLD_PLUS_ONE"> + <owner>mathp@chromium.org</owner> + <summary> + The eTLD+1 of a URL for which there was a high number of mismatches for the + heuristic prediction of the form field types. + </summary> +</rappor-metric> + +<rappor-metric name="Autofill.HighNumberOfServerMismatches" + type="ETLD_PLUS_ONE"> + <owner>mathp@chromium.org</owner> + <summary> + The eTLD+1 of a URL for which there was a high number of mismatches for the + server prediction of the form field types. + </summary> +</rappor-metric> + <rappor-metric name="ContentSettings.MixedScript.DisplayedShield" type="ETLD_PLUS_ONE"> <owner>lgarron@chromium.org</owner> |