Moves FrameHostMsg_SetCookie to a Mojo message

Adds a new BrowserAssociatedInterface to RenderFrameMessageFilter
and converts a single message (SetCookie) to Mojo.

BUG=612500
CQ_INCLUDE_TRYBOTS=master.tryserver.chromium.linux:linux_site_isolation

Review-Url: https://codereview.chromium.org/2167513003
Cr-Commit-Position: refs/heads/master@{#408173}
diff --git a/content/browser/frame_host/render_frame_message_filter.cc b/content/browser/frame_host/render_frame_message_filter.cc
index a1ccf83..a4a91b09 100644
--- a/content/browser/frame_host/render_frame_message_filter.cc
+++ b/content/browser/frame_host/render_frame_message_filter.cc
@@ -212,6 +212,7 @@
     net::URLRequestContextGetter* request_context,
     RenderWidgetHelper* render_widget_helper)
     : BrowserMessageFilter(FrameMsgStart),
+      BrowserAssociatedInterface<mojom::RenderFrameMessageFilter>(this, this),
 #if defined(ENABLE_PLUGINS)
       plugin_service_(plugin_service),
       profile_data_directory_(browser_context->GetPath()),
@@ -232,7 +233,6 @@
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(RenderFrameMessageFilter, message)
     IPC_MESSAGE_HANDLER(FrameHostMsg_CreateChildFrame, OnCreateChildFrame)
-    IPC_MESSAGE_HANDLER(FrameHostMsg_SetCookie, OnSetCookie)
     IPC_MESSAGE_HANDLER_DELAY_REPLY(FrameHostMsg_GetCookies, OnGetCookies)
     IPC_MESSAGE_HANDLER(FrameHostMsg_CookiesEnabled, OnCookiesEnabled)
     IPC_MESSAGE_HANDLER(FrameHostMsg_DownloadUrl, OnDownloadUrl)
@@ -261,6 +261,10 @@
   return handled;
 }
 
+void RenderFrameMessageFilter::OnDestruct() const {
+  BrowserThread::DeleteOnIOThread::Destruct(this);
+}
+
 void RenderFrameMessageFilter::DownloadUrl(int render_view_id,
                                            int render_frame_id,
                                            const GURL& url,
@@ -304,39 +308,6 @@
                  params.frame_owner_properties, *new_routing_id));
 }
 
-void RenderFrameMessageFilter::OnSetCookie(int render_frame_id,
-                                           const GURL& url,
-                                           const GURL& first_party_for_cookies,
-                                           const std::string& cookie) {
-  ChildProcessSecurityPolicyImpl* policy =
-      ChildProcessSecurityPolicyImpl::GetInstance();
-  if (!policy->CanAccessDataForOrigin(render_process_id_, url)) {
-    bad_message::ReceivedBadMessage(this,
-                                    bad_message::RFMF_SET_COOKIE_BAD_ORIGIN);
-    return;
-  }
-
-  net::CookieOptions options;
-  bool experimental_web_platform_features_enabled =
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableExperimentalWebPlatformFeatures);
-  const std::string enforce_strict_secure_group =
-      base::FieldTrialList::FindFullName(kEnforceStrictSecureExperiment);
-  if (experimental_web_platform_features_enabled ||
-      base::StartsWith(enforce_strict_secure_group, "Enabled",
-                       base::CompareCase::INSENSITIVE_ASCII)) {
-    options.set_enforce_strict_secure();
-  }
-  if (GetContentClient()->browser()->AllowSetCookie(
-          url, first_party_for_cookies, cookie, resource_context_,
-          render_process_id_, render_frame_id, options)) {
-    net::URLRequestContext* context = GetRequestContextForURL(url);
-    // Pass a null callback since we don't care about when the 'set' completes.
-    context->cookie_store()->SetCookieWithOptionsAsync(
-        url, cookie, options, net::CookieStore::SetCookiesCallback());
-  }
-}
-
 void RenderFrameMessageFilter::OnGetCookies(int render_frame_id,
                                             const GURL& url,
                                             const GURL& first_party_for_cookies,
@@ -460,6 +431,39 @@
       this, bad_message::RFMF_RENDERER_FAKED_ITS_OWN_DEATH);
 }
 
+void RenderFrameMessageFilter::SetCookie(int32_t render_frame_id,
+                                         const GURL& url,
+                                         const GURL& first_party_for_cookies,
+                                         const mojo::String& cookie) {
+  ChildProcessSecurityPolicyImpl* policy =
+      ChildProcessSecurityPolicyImpl::GetInstance();
+  if (!policy->CanAccessDataForOrigin(render_process_id_, url)) {
+    bad_message::ReceivedBadMessage(this,
+                                    bad_message::RFMF_SET_COOKIE_BAD_ORIGIN);
+    return;
+  }
+
+  net::CookieOptions options;
+  bool experimental_web_platform_features_enabled =
+      base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableExperimentalWebPlatformFeatures);
+  const std::string enforce_strict_secure_group =
+      base::FieldTrialList::FindFullName(kEnforceStrictSecureExperiment);
+  if (experimental_web_platform_features_enabled ||
+      base::StartsWith(enforce_strict_secure_group, "Enabled",
+                       base::CompareCase::INSENSITIVE_ASCII)) {
+    options.set_enforce_strict_secure();
+  }
+  if (GetContentClient()->browser()->AllowSetCookie(
+          url, first_party_for_cookies, cookie, resource_context_,
+          render_process_id_, render_frame_id, options)) {
+    net::URLRequestContext* context = GetRequestContextForURL(url);
+    // Pass a null callback since we don't care about when the 'set' completes.
+    context->cookie_store()->SetCookieWithOptionsAsync(
+        url, cookie, options, net::CookieStore::SetCookiesCallback());
+  }
+}
+
 #if defined(ENABLE_PLUGINS)
 
 void RenderFrameMessageFilter::OnGetPlugins(
diff --git a/content/browser/frame_host/render_frame_message_filter.h b/content/browser/frame_host/render_frame_message_filter.h
index f33be95..58460bc 100644
--- a/content/browser/frame_host/render_frame_message_filter.h
+++ b/content/browser/frame_host/render_frame_message_filter.h
@@ -10,6 +10,8 @@
 #include <set>
 
 #include "content/common/frame_replication_state.h"
+#include "content/common/render_frame_message_filter.mojom.h"
+#include "content/public/browser/browser_associated_interface.h"
 #include "content/public/browser/browser_message_filter.h"
 #include "content/public/common/three_d_api_types.h"
 #include "net/cookies/canonical_cookie.h"
@@ -41,7 +43,10 @@
 // with the routing id for a newly created RenderFrame.
 //
 // This object is created on the UI thread and used on the IO thread.
-class CONTENT_EXPORT RenderFrameMessageFilter : public BrowserMessageFilter {
+class CONTENT_EXPORT RenderFrameMessageFilter
+    : public BrowserMessageFilter,
+      public BrowserAssociatedInterface<mojom::RenderFrameMessageFilter>,
+      public NON_EXPORTED_BASE(mojom::RenderFrameMessageFilter) {
  public:
   RenderFrameMessageFilter(int render_process_id,
                            PluginServiceImpl* plugin_service,
@@ -51,6 +56,7 @@
 
   // BrowserMessageFilter methods:
   bool OnMessageReceived(const IPC::Message& message) override;
+  void OnDestruct() const override;
 
  protected:
   friend class TestSaveImageFromDataURL;
@@ -64,6 +70,9 @@
                            const bool use_prompt) const;
 
  private:
+  friend class BrowserThread;
+  friend class base::DeleteHelper<RenderFrameMessageFilter>;
+
   class OpenChannelToPpapiPluginCallback;
   class OpenChannelToPpapiBrokerCallback;
 
@@ -71,10 +80,6 @@
 
   void OnCreateChildFrame(const FrameHostMsg_CreateChildFrame_Params& params,
                           int* new_render_frame_id);
-  void OnSetCookie(int render_frame_id,
-                   const GURL& url,
-                   const GURL& first_party_for_cookies,
-                   const std::string& cookie);
   void OnGetCookies(int render_frame_id,
                     const GURL& url,
                     const GURL& first_party_for_cookies,
@@ -112,6 +117,13 @@
 
   void OnRenderProcessGone();
 
+  // mojom::RenderFrameMessageFilter:
+  void SetCookie(int32_t render_frame_id,
+                 const GURL& url,
+                 const GURL& first_party_for_cookies,
+                 const mojo::String& cookie) override;
+
+
 #if defined(ENABLE_PLUGINS)
   void OnGetPlugins(bool refresh, IPC::Message* reply_msg);
   void GetPluginsCallback(IPC::Message* reply_msg,
diff --git a/content/browser/frame_host/render_frame_message_filter_browsertest.cc b/content/browser/frame_host/render_frame_message_filter_browsertest.cc
index 1cd3cf0..4e822481 100644
--- a/content/browser/frame_host/render_frame_message_filter_browsertest.cc
+++ b/content/browser/frame_host/render_frame_message_filter_browsertest.cc
@@ -9,8 +9,10 @@
 #include "base/test/histogram_tester.h"
 #include "content/browser/bad_message.h"
 #include "content/browser/frame_host/frame_tree.h"
+#include "content/browser/frame_host/render_frame_message_filter.h"
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/common/frame_messages.h"
+#include "content/common/render_frame_message_filter.mojom.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
@@ -215,11 +217,16 @@
   RenderProcessHostWatcher main_frame_killed(
       tab->GetMainFrame()->GetProcess(),
       RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT);
-  FrameHostMsg_SetCookie illegal_set_cookie(tab->GetMainFrame()->GetRoutingID(),
-                                            GURL("https://baz.com/"),
-                                            GURL("https://baz.com/"), "pwn=ed");
-  IPC::IpcSecurityTestUtil::PwnMessageReceived(
-      tab->GetMainFrame()->GetProcess()->GetChannel(), illegal_set_cookie);
+
+  RenderProcessHostImpl* process =
+      static_cast<RenderProcessHostImpl*>(tab->GetMainFrame()->GetProcess());
+  BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &mojom::RenderFrameMessageFilter::SetCookie,
+          base::Unretained(process->render_frame_message_filter_for_testing()),
+          tab->GetMainFrame()->GetRoutingID(), GURL("https://baz.com/"),
+          GURL("https://baz.com/"), "pwn=ed"));
 
   main_frame_killed.Wait();
 
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index e71e6c5..f3aa0e6 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -877,7 +877,8 @@
           storage_partition_impl_->GetDOMStorageContext(),
           storage_partition_impl_->GetCacheStorageContext()));
   AddFilter(render_message_filter.get());
-  AddFilter(new RenderFrameMessageFilter(
+
+  render_frame_message_filter_ = new RenderFrameMessageFilter(
       GetID(),
 #if defined(ENABLE_PLUGINS)
       PluginServiceImpl::GetInstance(),
@@ -886,7 +887,9 @@
 #endif
       GetBrowserContext(),
       request_context.get(),
-      widget_helper_.get()));
+      widget_helper_.get());
+  AddFilter(render_frame_message_filter_.get());
+
   BrowserContext* browser_context = GetBrowserContext();
   ResourceContext* resource_context = browser_context->GetResourceContext();
 
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 481fad9..ea1d9eaa 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -61,6 +61,7 @@
 class PermissionServiceContext;
 class PeerConnectionTrackerHost;
 class RendererMainThread;
+class RenderFrameMessageFilter;
 class RenderWidgetHelper;
 class RenderWidgetHost;
 class RenderWidgetHostImpl;
@@ -246,6 +247,10 @@
   }
 #endif
 
+  RenderFrameMessageFilter* render_frame_message_filter_for_testing() const {
+    return render_frame_message_filter_.get();
+  }
+
   MessagePortMessageFilter* message_port_message_filter() const {
     return message_port_message_filter_.get();
   }
@@ -378,6 +383,8 @@
   // IO thread.
   scoped_refptr<RenderWidgetHelper> widget_helper_;
 
+  scoped_refptr<RenderFrameMessageFilter> render_frame_message_filter_;
+
   // The filter for MessagePort messages coming from the renderer.
   scoped_refptr<MessagePortMessageFilter> message_port_message_filter_;
 
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index 410d4b7..c5d320a 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -245,6 +245,7 @@
     "image_downloader/image_downloader.mojom",
     "leveldb_wrapper.mojom",
     "process_control.mojom",
+    "render_frame_message_filter.mojom",
     "render_widget_window_tree_client_factory.mojom",
     "service_worker/embedded_worker_setup.mojom",
     "storage_partition_service.mojom",
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h
index 07144d7..c1b4fd4 100644
--- a/content/common/frame_messages.h
+++ b/content/common/frame_messages.h
@@ -1156,14 +1156,6 @@
 IPC_MESSAGE_ROUTED1(FrameHostMsg_DomOperationResponse,
                     std::string  /* json_string */)
 
-// Used to set a cookie. The cookie is set asynchronously, but will be
-// available to a subsequent FrameHostMsg_GetCookies request.
-IPC_MESSAGE_CONTROL4(FrameHostMsg_SetCookie,
-                     int /* render_frame_id */,
-                     GURL /* url */,
-                     GURL /* first_party_for_cookies */,
-                     std::string /* cookie */)
-
 // Used to get cookies for the given URL. This may block waiting for a
 // previous SetCookie message to be processed.
 IPC_SYNC_MESSAGE_CONTROL3_1(FrameHostMsg_GetCookies,
diff --git a/content/common/render_frame_message_filter.mojom b/content/common/render_frame_message_filter.mojom
new file mode 100644
index 0000000..909c4f379
--- /dev/null
+++ b/content/common/render_frame_message_filter.mojom
@@ -0,0 +1,14 @@
+// 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 content.mojom;
+
+import "url/mojo/url.mojom";
+
+interface RenderFrameMessageFilter {
+  // Sets a cookie. The cookie is set asynchronously, but will be available to
+  // any subsequent FrameHostMsg_GetCookies request.
+  SetCookie(int32 render_frame_id, url.mojom.Url url,
+      url.mojom.Url first_party_for_cookies, string cookie);
+};
diff --git a/content/content_common_mojo_bindings.gyp b/content/content_common_mojo_bindings.gyp
index 11d321e..de48c54 100644
--- a/content/content_common_mojo_bindings.gyp
+++ b/content/content_common_mojo_bindings.gyp
@@ -15,6 +15,7 @@
           'common/image_downloader/image_downloader.mojom',
           'common/leveldb_wrapper.mojom',
           'common/process_control.mojom',
+          'common/render_frame_message_filter.mojom',
           'common/service_worker/embedded_worker_setup.mojom',
           'common/storage_partition_service.mojom',
         ],
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc
index 4ce4b52..3e5b622 100644
--- a/content/renderer/render_thread_impl.cc
+++ b/content/renderer/render_thread_impl.cc
@@ -1957,6 +1957,13 @@
 }
 #endif
 
+mojom::RenderFrameMessageFilter*
+RenderThreadImpl::render_frame_message_filter() {
+  if (!render_frame_message_filter_)
+    GetChannel()->GetRemoteAssociatedInterface(&render_frame_message_filter_);
+  return render_frame_message_filter_.get();
+}
+
 gpu::GpuChannelHost* RenderThreadImpl::GetGpuChannel() {
   if (!gpu_channel_)
     return nullptr;
diff --git a/content/renderer/render_thread_impl.h b/content/renderer/render_thread_impl.h
index c12aa2d..bb0553c 100644
--- a/content/renderer/render_thread_impl.h
+++ b/content/renderer/render_thread_impl.h
@@ -28,6 +28,7 @@
 #include "content/common/frame.mojom.h"
 #include "content/common/frame_replication_state.h"
 #include "content/common/gpu_process_launch_causes.h"
+#include "content/common/render_frame_message_filter.mojom.h"
 #include "content/common/storage_partition_service.mojom.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/renderer/gpu/compositor_dependencies.h"
@@ -334,6 +335,8 @@
     return vc_manager_.get();
   }
 
+  mojom::RenderFrameMessageFilter* render_frame_message_filter();
+
   // Get the GPU channel. Returns NULL if the channel is not established or
   // has been lost.
   gpu::GpuChannelHost* GetGpuChannel();
@@ -702,6 +705,8 @@
 
   mojom::StoragePartitionServicePtr storage_partition_service_;
 
+  mojom::RenderFrameMessageFilterAssociatedPtr render_frame_message_filter_;
+
   bool is_renderer_suspended_;
 
   DISALLOW_COPY_AND_ASSIGN(RenderThreadImpl);
diff --git a/content/renderer/renderer_webcookiejar_impl.cc b/content/renderer/renderer_webcookiejar_impl.cc
index 36706a0..afabadc 100644
--- a/content/renderer/renderer_webcookiejar_impl.cc
+++ b/content/renderer/renderer_webcookiejar_impl.cc
@@ -8,6 +8,7 @@
 #include "content/common/frame_messages.h"
 #include "content/public/renderer/content_renderer_client.h"
 #include "content/renderer/render_frame_impl.h"
+#include "content/renderer/render_thread_impl.h"
 
 using blink::WebString;
 using blink::WebURL;
@@ -18,8 +19,8 @@
     const WebURL& url, const WebURL& first_party_for_cookies,
     const WebString& value) {
   std::string value_utf8 = base::UTF16ToUTF8(base::StringPiece16(value));
-  sender_->Send(new FrameHostMsg_SetCookie(
-      sender_->GetRoutingID(), url, first_party_for_cookies, value_utf8));
+  RenderThreadImpl::current()->render_frame_message_filter()->SetCookie(
+      sender_->GetRoutingID(), url, first_party_for_cookies, value_utf8);
 }
 
 WebString RendererWebCookieJarImpl::cookies(