Index: content/browser/renderer_host/render_process_host_impl.cc |
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc |
index ce8540f0dcf32f1506e42c2170abbca5e9d93ad0..3e5d646732fadeec9d1e937a964f0a71e1c0721a 100644 |
--- a/content/browser/renderer_host/render_process_host_impl.cc |
+++ b/content/browser/renderer_host/render_process_host_impl.cc |
@@ -175,6 +175,7 @@ |
#include "ipc/ipc_switches.h" |
#include "media/base/media_switches.h" |
#include "mojo/edk/embedder/embedder.h" |
+#include "mojo/public/cpp/bindings/associated_interface_ptr.h" |
#include "net/url_request/url_request_context_getter.h" |
#include "ppapi/shared_impl/ppapi_switches.h" |
#include "services/shell/public/cpp/connection.h" |
@@ -249,6 +250,7 @@ |
namespace content { |
namespace { |
+const char kRendererInterfaceKeyName[] = "mojom_renderer_interface"; |
const char kSiteProcessMapKeyName[] = "content_site_process_map"; |
#ifdef ENABLE_WEBRTC |
@@ -365,6 +367,21 @@ SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) { |
return map; |
} |
+// Holds a Mojo associated interface proxy in an RPH's user data. |
+template <typename Interface> |
+class AssociatedInterfaceHolder : public base::SupportsUserData::Data { |
+ public: |
+ AssociatedInterfaceHolder() {} |
+ ~AssociatedInterfaceHolder() override {} |
+ |
+ mojo::AssociatedInterfacePtr<Interface>& proxy() { return proxy_; } |
+ |
+ private: |
+ mojo::AssociatedInterfacePtr<Interface> proxy_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AssociatedInterfaceHolder); |
+}; |
+ |
#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) |
// This static member variable holds the zygote communication information for |
// the renderer. |
@@ -838,7 +855,7 @@ bool RenderProcessHostImpl::Init() { |
// Ensure that the remote associated interfaces are re-initialized on next |
// access since they're associated with a specific Channel instance. |
remote_route_provider_.reset(); |
- renderer_interface_.reset(); |
+ RemoveUserData(kRendererInterfaceKeyName); |
base::CommandLine::StringType renderer_prefix; |
// A command prefix is something prepended to the command line of the spawned |
@@ -1394,12 +1411,28 @@ mojom::RouteProvider* RenderProcessHostImpl::GetRemoteRouteProvider() { |
return remote_route_provider_.get(); |
} |
-mojom::Renderer* RenderProcessHostImpl::GetRendererInterface() { |
- if (!renderer_interface_) { |
- DCHECK(channel_); |
- channel_->GetRemoteAssociatedInterface(&renderer_interface_); |
+// static |
+mojom::Renderer* RenderProcessHostImpl::GetRendererInterface( |
+ RenderProcessHost* host) { |
+ AssociatedInterfaceHolder<mojom::Renderer>* holder = |
+ static_cast<AssociatedInterfaceHolder<mojom::Renderer>*>( |
+ host->GetUserData(kRendererInterfaceKeyName)); |
+ if (!holder) { |
+ holder = new AssociatedInterfaceHolder<mojom::Renderer>; |
+ |
+ // Takes ownership of |holder|. |
+ host->SetUserData(kRendererInterfaceKeyName, holder); |
+ |
+ // In tests, GetChannel() is null. We bind the proxy to a dead-end endpoint |
+ // so that its outgoing requests are be silently dropped. |
+ IPC::ChannelProxy* channel = host->GetChannel(); |
+ if (channel) |
+ channel->GetRemoteAssociatedInterface(&holder->proxy()); |
+ else |
+ mojo::GetDummyProxyForTesting(&holder->proxy()); |
} |
- return renderer_interface_.get(); |
+ |
+ return holder->proxy().get(); |
} |
void RenderProcessHostImpl::AddRoute(int32_t routing_id, |