Adds associated interface support between RenderFrameHost and RenderFrame.

Introduces a new content::AssociatedInterfaceRegistry and
content::AssociatedInterfaceProvider to serve as Channel-associated
interface counterparts to their shell namesakes.

RenderFrameHost and RenderFrame each have both of these things on them,
and they're routed to the other side using a new RouteProvider interface
buried in RenderProcessHostImpl / ChildThreadImpl on either end.

Also adds a WebContentsInterfaceRegistry to every WebContents,
and a helper WebContentsFrameBindingSet<T> to allow consumers to
very easily manage the lifetime of associated interface bindings
for each frame in a WebContents.

See the follow-up patch for example usage.

Part a series of CLs to enable and demonstrate WebContents associated
interfaces:

  1. https://codereview.chromium.org/2309513002
  2. https://codereview.chromium.org/2316963005
  3. This CL
  4. https://codereview.chromium.org/2310583002

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

Review-Url: https://codereview.chromium.org/2310563002
Cr-Commit-Position: refs/heads/master@{#418717}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 683bd71..be05e4a4c 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -104,6 +104,7 @@
 #include "content/public/browser/security_style_explanations.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/user_metrics.h"
+#include "content/public/browser/web_contents_binding_set.h"
 #include "content/public/browser/web_contents_delegate.h"
 #include "content/public/common/bindings_policy.h"
 #include "content/public/common/browser_plugin_guest_mode.h"
@@ -459,6 +460,9 @@
 
   rwh_input_event_router_.reset();
 
+  for (auto& entry : binding_sets_)
+    entry.second->CloseAllBindings();
+
   WebContentsImpl* outermost = GetOutermostWebContents();
   if (GetFocusedWebContents() == this && this != outermost) {
     // If the current WebContents is in focus, unset it.
@@ -986,6 +990,16 @@
   UpdateZoom(level);
 }
 
+base::Closure WebContentsImpl::AddBindingSet(
+    const std::string& interface_name,
+    WebContentsBindingSet* binding_set) {
+  auto result =
+      binding_sets_.insert(std::make_pair(interface_name, binding_set));
+  DCHECK(result.second);
+  return base::Bind(&WebContentsImpl::RemoveBindingSet,
+                    weak_factory_.GetWeakPtr(), interface_name);
+}
+
 void WebContentsImpl::UpdateDeviceScaleFactor(double device_scale_factor) {
   SendPageMessage(
       new PageMsg_SetDeviceScaleFactor(MSG_ROUTING_NONE, device_scale_factor));
@@ -4040,6 +4054,15 @@
   return OnMessageReceived(NULL, render_frame_host, message);
 }
 
+void WebContentsImpl::OnAssociatedInterfaceRequest(
+    RenderFrameHost* render_frame_host,
+    const std::string& interface_name,
+    mojo::ScopedInterfaceEndpointHandle handle) {
+  auto it = binding_sets_.find(interface_name);
+  if (it != binding_sets_.end())
+    it->second->OnRequestForFrame(render_frame_host, std::move(handle));
+}
+
 const GURL& WebContentsImpl::GetMainFrameLastCommittedURL() const {
   return GetLastCommittedURL();
 }
@@ -5209,4 +5232,10 @@
   dialog_manager_ = dialog_manager;
 }
 
+void WebContentsImpl::RemoveBindingSet(const std::string& interface_name) {
+  auto it = binding_sets_.find(interface_name);
+  if (it != binding_sets_.end())
+    binding_sets_.erase(it);
+}
+
 }  // namespace content