Convert RapporRecorder to use mojo.

Manually tested by printf'ing the arguments to RapporRecorderImpl
methods and navigating a bunch of tabs. The args looked the same as
for ChromeRenderMessageFilter prior to this CL.

BUG=577685

Review-Url: https://codereview.chromium.org/2376403003
Cr-Commit-Position: refs/heads/master@{#425248}
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 9a031b0..1d03f4f 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1363,6 +1363,7 @@
     "//components/proxy_config",
     "//components/query_parser",
     "//components/rappor",
+    "//components/rappor:rappor_recorder",
     "//components/renderer_context_menu",
     "//components/resources",
     "//components/safe_browsing_db",
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index dd1a1e2e..53c22049 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -134,6 +134,7 @@
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/prefs/scoped_user_pref_update.h"
+#include "components/rappor/rappor_recorder_impl.h"
 #include "components/rappor/rappor_utils.h"
 #include "components/security_interstitials/core/ssl_error_ui.h"
 #include "components/signin/core/common/profile_management_switches.h"
@@ -2895,6 +2896,10 @@
   registry->AddInterface(
       base::Bind(&BudgetServiceImpl::Create, render_process_host->GetID()),
       ui_task_runner);
+  registry->AddInterface(
+      base::Bind(&rappor::RapporRecorderImpl::Create,
+                 g_browser_process->rappor_service()),
+      ui_task_runner);
 
 #if defined(OS_CHROMEOS)
   registry->AddInterface<metrics::mojom::LeakDetector>(
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json
index 855a9ec9..23481711 100644
--- a/chrome/browser/chrome_content_browser_manifest_overlay.json
+++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -8,6 +8,7 @@
         "autofill::mojom::PasswordManagerDriver",
         "extensions::StashService",
         "metrics::mojom::LeakDetector",
+        "rappor::mojom::RapporRecorder",
         "startup_metric_utils::mojom::StartupMetricHost",
         "translate::mojom::ContentTranslateDriver"
       ],
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc
index f6f74e7..44b6ad0 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.cc
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc
@@ -25,8 +25,6 @@
 #include "components/content_settings/core/browser/cookie_settings.h"
 #include "components/network_hints/common/network_hints_common.h"
 #include "components/network_hints/common/network_hints_messages.h"
-#include "components/rappor/rappor_service.h"
-#include "components/rappor/rappor_utils.h"
 #include "components/web_cache/browser/web_cache_manager.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/render_process_host.h"
@@ -89,8 +87,6 @@
 #endif
     IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FieldTrialActivated,
                         OnFieldTrialActivated)
-    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RecordRappor, OnRecordRappor)
-    IPC_MESSAGE_HANDLER(ChromeViewHostMsg_RecordRapporURL, OnRecordRapporURL)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
 
@@ -105,8 +101,6 @@
     case ChromeViewHostMsg_IsCrashReportingEnabled::ID:
 #endif
     case ChromeViewHostMsg_UpdatedCacheStats::ID:
-    case ChromeViewHostMsg_RecordRappor::ID:
-    case ChromeViewHostMsg_RecordRapporURL::ID:
       *thread = BrowserThread::UI;
       break;
     default:
@@ -363,17 +357,3 @@
   // and activates the trial.
   base::FieldTrialList::FindFullName(trial_name);
 }
-
-void ChromeRenderMessageFilter::OnRecordRappor(const std::string& metric,
-                                               const std::string& sample) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  rappor::SampleString(g_browser_process->rappor_service(), metric,
-                       rappor::ETLD_PLUS_ONE_RAPPOR_TYPE, sample);
-}
-
-void ChromeRenderMessageFilter::OnRecordRapporURL(const std::string& metric,
-                                                  const GURL& sample) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  rappor::SampleDomainAndRegistryFromGURL(g_browser_process->rappor_service(),
-                                          metric, sample);
-}
diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.h b/chrome/browser/renderer_host/chrome_render_message_filter.h
index 2ed27b0c..171e6c8 100644
--- a/chrome/browser/renderer_host/chrome_render_message_filter.h
+++ b/chrome/browser/renderer_host/chrome_render_message_filter.h
@@ -129,8 +129,6 @@
   // Called when a message is received from a renderer that a trial has been
   // activated (ChromeViewHostMsg_FieldTrialActivated).
   void OnFieldTrialActivated(const std::string& trial_name);
-  void OnRecordRappor(const std::string& metric, const std::string& sample);
-  void OnRecordRapporURL(const std::string& metric, const GURL& sample);
 
   const int render_process_id_;
 
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index e0b8118..e90ed2d4 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -639,13 +639,3 @@
 // Sent by the renderer to indicate that a fields trial has been activated.
 IPC_MESSAGE_CONTROL1(ChromeViewHostMsg_FieldTrialActivated,
                      std::string /* name */)
-
-// Record a sample string to a Rappor metric.
-IPC_MESSAGE_CONTROL2(ChromeViewHostMsg_RecordRappor,
-                     std::string /* metric */,
-                     std::string /* sample */)
-
-// Record a domain and registry of a url to a Rappor metric.
-IPC_MESSAGE_CONTROL2(ChromeViewHostMsg_RecordRapporURL,
-                     std::string /* metric */,
-                     GURL /* sample url */)
diff --git a/chrome/renderer/BUILD.gn b/chrome/renderer/BUILD.gn
index def8295..5550218 100644
--- a/chrome/renderer/BUILD.gn
+++ b/chrome/renderer/BUILD.gn
@@ -104,6 +104,7 @@
     "//components/password_manager/content/renderer",
     "//components/plugins/renderer",
     "//components/printing/renderer",
+    "//components/rappor/public/interfaces",
     "//components/resources:components_resources",
     "//components/startup_metric_utils/common:interfaces",
     "//components/subresource_filter/content/renderer",
diff --git a/chrome/renderer/DEPS b/chrome/renderer/DEPS
index 5aa66ed..f5d1411 100644
--- a/chrome/renderer/DEPS
+++ b/chrome/renderer/DEPS
@@ -24,6 +24,7 @@
   "+components/plugins/renderer",
   "+components/printing/common",
   "+components/printing/renderer",
+  "+components/rappor/public/interfaces",
   "+components/signin/core/common",
   "+components/spellcheck/common",
   "+components/spellcheck/renderer",
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 7bf820e..67923a0 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -1337,12 +1337,16 @@
 
 void ChromeContentRendererClient::RecordRappor(const std::string& metric,
                                                const std::string& sample) {
-  RenderThread::Get()->Send(new ChromeViewHostMsg_RecordRappor(metric, sample));
+  if (!rappor_recorder_)
+    RenderThread::Get()->GetRemoteInterfaces()->GetInterface(&rappor_recorder_);
+  rappor_recorder_->RecordRappor(metric, sample);
 }
 
 void ChromeContentRendererClient::RecordRapporURL(const std::string& metric,
                                                   const GURL& url) {
-  RenderThread::Get()->Send(new ChromeViewHostMsg_RecordRapporURL(metric, url));
+  if (!rappor_recorder_)
+    RenderThread::Get()->GetRemoteInterfaces()->GetInterface(&rappor_recorder_);
+  rappor_recorder_->RecordRapporURL(metric, url);
 }
 
 std::unique_ptr<blink::WebAppBannerClient>
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 2a834f1..f366548 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -16,6 +16,7 @@
 #include "base/compiler_specific.h"
 #include "base/gtest_prod_util.h"
 #include "base/strings/string16.h"
+#include "components/rappor/public/interfaces/rappor_recorder.mojom.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "ipc/ipc_channel_proxy.h"
 #include "v8/include/v8.h"
@@ -227,6 +228,8 @@
                             blink::WebPluginParams* params);
 #endif
 
+  rappor::mojom::RapporRecorderPtr rappor_recorder_;
+
   std::unique_ptr<ChromeRenderThreadObserver> chrome_observer_;
   std::unique_ptr<web_cache::WebCacheImpl> web_cache_impl_;
 
@@ -254,6 +257,8 @@
 #if defined(OS_CHROMEOS)
   std::unique_ptr<LeakDetectorRemoteClient> leak_detector_remote_client_;
 #endif
+
+  DISALLOW_COPY_AND_ASSIGN(ChromeContentRendererClient);
 };
 
 #endif  // CHROME_RENDERER_CHROME_CONTENT_RENDERER_CLIENT_H_
diff --git a/components/rappor/BUILD.gn b/components/rappor/BUILD.gn
index 5b9e11d..be595ad 100644
--- a/components/rappor/BUILD.gn
+++ b/components/rappor/BUILD.gn
@@ -47,6 +47,23 @@
   ]
 }
 
+static_library("rappor_recorder") {
+  sources = [
+    "rappor_recorder_impl.cc",
+    "rappor_recorder_impl.h",
+  ]
+
+  public_deps = [
+    "//base",
+    "//components/rappor/public/interfaces",
+  ]
+
+  deps = [
+    ":rappor",
+    "//mojo/public/cpp/bindings",
+  ]
+}
+
 static_library("test_support") {
   testonly = true
   sources = [
diff --git a/components/rappor/DEPS b/components/rappor/DEPS
index 21030ecc..dd45846 100644
--- a/components/rappor/DEPS
+++ b/components/rappor/DEPS
@@ -4,6 +4,7 @@
   "+components/prefs",
   "+components/variations",
   "+crypto",
+  "+mojo/public/cpp",
   "+net",
   "+third_party/smhasher",
 ]
diff --git a/components/rappor/public/interfaces/BUILD.gn b/components/rappor/public/interfaces/BUILD.gn
new file mode 100644
index 0000000..1c9a554
--- /dev/null
+++ b/components/rappor/public/interfaces/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("interfaces") {
+  sources = [
+    "rappor_recorder.mojom",
+  ]
+
+  public_deps = [
+    "//url/mojo:url_mojom_gurl",
+  ]
+}
diff --git a/components/rappor/public/interfaces/OWNERS b/components/rappor/public/interfaces/OWNERS
new file mode 100644
index 0000000..08850f4
--- /dev/null
+++ b/components/rappor/public/interfaces/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/components/rappor/public/interfaces/rappor_recorder.mojom b/components/rappor/public/interfaces/rappor_recorder.mojom
new file mode 100644
index 0000000..38647b4
--- /dev/null
+++ b/components/rappor/public/interfaces/rappor_recorder.mojom
@@ -0,0 +1,19 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module rappor.mojom;
+
+import "url/mojo/url.mojom";
+
+// Records aggregate, privacy-preserving samples from the renderers.
+// See: https://www.chromium.org/developers/design-documents/rappor
+interface RapporRecorder {
+  // Records a sample string to a Rappor privacy-preserving metric.
+  // See: https://www.chromium.org/developers/design-documents/rappor
+  RecordRappor(string metric, string sample);
+
+  // Records a domain and registry of a url to a Rappor privacy-preserving
+  // metric. See: https://www.chromium.org/developers/design-documents/rappor
+  RecordRapporURL(string metric, url.mojom.Url url);
+};
diff --git a/components/rappor/rappor_recorder_impl.cc b/components/rappor/rappor_recorder_impl.cc
new file mode 100644
index 0000000..101c067
--- /dev/null
+++ b/components/rappor/rappor_recorder_impl.cc
@@ -0,0 +1,37 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/rappor/rappor_recorder_impl.h"
+
+#include "components/rappor/rappor_service.h"
+#include "components/rappor/rappor_utils.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace rappor {
+
+RapporRecorderImpl::RapporRecorderImpl(RapporService* rappor_service)
+    : rappor_service_(rappor_service) {}
+
+RapporRecorderImpl::~RapporRecorderImpl() = default;
+
+// static
+void RapporRecorderImpl::Create(RapporService* rappor_service,
+                                mojom::RapporRecorderRequest request) {
+  mojo::MakeStrongBinding(base::MakeUnique<RapporRecorderImpl>(rappor_service),
+                          std::move(request));
+}
+
+void RapporRecorderImpl::RecordRappor(const std::string& metric,
+                                      const std::string& sample) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  SampleString(rappor_service_, metric, ETLD_PLUS_ONE_RAPPOR_TYPE, sample);
+}
+
+void RapporRecorderImpl::RecordRapporURL(const std::string& metric,
+                                         const GURL& sample) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+  SampleDomainAndRegistryFromGURL(rappor_service_, metric, sample);
+}
+
+}  // namespace rappor
diff --git a/components/rappor/rappor_recorder_impl.h b/components/rappor/rappor_recorder_impl.h
new file mode 100644
index 0000000..d558a274
--- /dev/null
+++ b/components/rappor/rappor_recorder_impl.h
@@ -0,0 +1,41 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_RAPPOR_RAPPOR_RECORDER_IMPL_H_
+#define COMPONENTS_RAPPOR_RAPPOR_RECORDER_IMPL_H_
+
+#include "base/threading/thread_checker.h"
+#include "components/rappor/public/interfaces/rappor_recorder.mojom.h"
+
+class GURL;
+
+namespace rappor {
+
+class RapporService;
+
+// Records aggregate, privacy-preserving samples from the renderers.
+// See https://www.chromium.org/developers/design-documents/rappor
+class RapporRecorderImpl : public mojom::RapporRecorder {
+ public:
+  explicit RapporRecorderImpl(RapporService* rappor_service);
+  ~RapporRecorderImpl() override;
+
+  static void Create(RapporService* rappor_service,
+                     mojom::RapporRecorderRequest request);
+
+ private:
+  // rappor::mojom::RapporRecorder:
+  void RecordRappor(const std::string& metric,
+                    const std::string& sample) override;
+  void RecordRapporURL(const std::string& metric, const GURL& sample) override;
+
+  RapporService* rappor_service_;
+  base::ThreadChecker thread_checker_;
+
+  DISALLOW_COPY_AND_ASSIGN(RapporRecorderImpl);
+};
+
+}  // namespace rappor
+
+#endif  // COMPONENTS_RAPPOR_RAPPOR_RECORDER_IMPL_H_