summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormathp <mathp@chromium.org>2015-03-17 17:16:16 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-18 00:17:22 +0000
commit94e3f0b1ec9dab48251c7322c1a3252bb7a5a8c6 (patch)
tree51f9d9b891d9d1531d909e59371cd51b8596ba57
parentd0e32d4246d27108922fdd2abbafa7cbcd182763 (diff)
downloadchromium_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.cc4
-rw-r--r--android_webview/native/aw_autofill_client.h1
-rw-r--r--chrome/browser/ui/autofill/chrome_autofill_client.cc5
-rw-r--r--chrome/browser/ui/autofill/chrome_autofill_client.h1
-rw-r--r--components/autofill.gypi2
-rw-r--r--components/autofill/core/DEPS1
-rw-r--r--components/autofill/core/browser/BUILD.gn2
-rw-r--r--components/autofill/core/browser/autofill_client.h7
-rw-r--r--components/autofill/core/browser/autofill_manager.cc3
-rw-r--r--components/autofill/core/browser/autofill_metrics_unittest.cc194
-rw-r--r--components/autofill/core/browser/form_structure.cc26
-rw-r--r--components/autofill/core/browser/form_structure.h7
-rw-r--r--components/autofill/core/browser/test_autofill_client.cc7
-rw-r--r--components/autofill/core/browser/test_autofill_client.h7
-rw-r--r--tools/metrics/rappor/rappor.xml18
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>