Make sure Widget mojo interface is constructed for RenderWidgetHosts.

We require that a Widget interface exists for a RenderWidgetHost. Ensure
that it is plumbed correctly so that in has a bound request interface
always.

BUG=722928

Cq-Include-Trybots: master.tryserver.chromium.linux:linux_site_isolation
Change-Id: Ibc786aca96b2ae332e4d7ff54ecd07f10ce143db
Reviewed-on: https://chromium-review.googlesource.com/598121
Commit-Queue: Dave Tapuska <[email protected]>
Reviewed-by: Daniel Cheng <[email protected]>
Reviewed-by: Antoine Labour <[email protected]>
Cr-Commit-Position: refs/heads/master@{#492475}
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 3dd6108..7eb27fc 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -83,6 +83,7 @@
 #include "content/common/renderer.mojom.h"
 #include "content/common/site_isolation_policy.h"
 #include "content/common/swapped_out_messages.h"
+#include "content/common/widget.mojom.h"
 #include "content/public/browser/ax_event_notification_details.h"
 #include "content/public/browser/browser_accessibility_state.h"
 #include "content/public/browser/browser_context.h"
@@ -521,6 +522,9 @@
                                     weak_ptr_factory_.GetWeakPtr())));
 
   if (widget_routing_id != MSG_ROUTING_NONE) {
+    mojom::WidgetPtr widget;
+    GetRemoteInterfaces()->GetInterface(&widget);
+
     // TODO(avi): Once RenderViewHostImpl has-a RenderWidgetHostImpl, the main
     // render frame should probably start owning the RenderWidgetHostImpl,
     // so this logic checking for an already existing RWHI should be removed.
@@ -529,11 +533,14 @@
         RenderWidgetHostImpl::FromID(GetProcess()->GetID(), widget_routing_id);
     if (!render_widget_host_) {
       DCHECK(frame_tree_node->parent());
+
       render_widget_host_ = new RenderWidgetHostImpl(rwh_delegate, GetProcess(),
-                                                     widget_routing_id, hidden);
+                                                     widget_routing_id,
+                                                     std::move(widget), hidden);
       render_widget_host_->set_owned_by_render_frame_host(true);
     } else {
       DCHECK(!render_widget_host_->owned_by_render_frame_host());
+      render_widget_host_->SetWidget(std::move(widget));
     }
     render_widget_host_->input_router()->SetFrameTreeNodeId(
         frame_tree_node_->frame_tree_node_id());
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
index 02c22ff4..8b447d1 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
@@ -24,6 +24,7 @@
 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
 #include "content/browser/frame_host/cross_process_frame_connector.h"
 #include "content/browser/gpu/compositor_util.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/common/view_messages.h"
@@ -84,8 +85,10 @@
     MockRenderProcessHost* process_host =
         new MockRenderProcessHost(browser_context_.get());
     int32_t routing_id = process_host->GetNextRoutingID();
-    widget_host_ =
-        new RenderWidgetHostImpl(&delegate_, process_host, routing_id, false);
+    mojom::WidgetPtr widget;
+    widget_impl_ = base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+    widget_host_ = new RenderWidgetHostImpl(
+        &delegate_, process_host, routing_id, std::move(widget), false);
     view_ = RenderWidgetHostViewChildFrame::Create(widget_host_);
 
     test_frame_connector_ = new MockCrossProcessFrameConnector();
@@ -139,6 +142,7 @@
 
   // Tests should set these to NULL if they've already triggered their
   // destruction.
+  std::unique_ptr<MockWidgetImpl> widget_impl_;
   RenderWidgetHostImpl* widget_host_;
   RenderWidgetHostViewChildFrame* view_;
   MockCrossProcessFrameConnector* test_frame_connector_;
diff --git a/content/browser/frame_host/render_widget_host_view_guest_unittest.cc b/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
index fcbb45b8..1354e32 100644
--- a/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
+++ b/content/browser/frame_host/render_widget_host_view_guest_unittest.cc
@@ -19,6 +19,7 @@
 #include "content/browser/browser_plugin/browser_plugin_guest.h"
 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
 #include "content/browser/gpu/compositor_util.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/common/view_messages.h"
@@ -52,8 +53,11 @@
     MockRenderProcessHost* process_host =
         new MockRenderProcessHost(browser_context_.get());
     int32_t routing_id = process_host->GetNextRoutingID();
-    widget_host_ =
-        new RenderWidgetHostImpl(&delegate_, process_host, routing_id, false);
+    mojom::WidgetPtr widget;
+    widget_impl_ = base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+
+    widget_host_ = new RenderWidgetHostImpl(
+        &delegate_, process_host, routing_id, std::move(widget), false);
     view_ = RenderWidgetHostViewGuest::Create(
         widget_host_, NULL,
         (new TestRenderWidgetHostView(widget_host_))->GetWeakPtr());
@@ -83,6 +87,7 @@
 
   // Tests should set these to NULL if they've already triggered their
   // destruction.
+  std::unique_ptr<MockWidgetImpl> widget_impl_;
   RenderWidgetHostImpl* widget_host_;
   RenderWidgetHostViewGuest* view_;
 
@@ -153,8 +158,11 @@
         web_contents_.get(), &browser_plugin_guest_delegate_);
 
     int32_t routing_id = process_host->GetNextRoutingID();
-    widget_host_ =
-        new RenderWidgetHostImpl(&delegate_, process_host, routing_id, false);
+    mojom::WidgetPtr widget;
+    widget_impl_ = base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+
+    widget_host_ = new RenderWidgetHostImpl(
+        &delegate_, process_host, routing_id, std::move(widget), false);
     view_ = RenderWidgetHostViewGuest::Create(
         widget_host_, browser_plugin_guest_,
         (new TestRenderWidgetHostView(widget_host_))->GetWeakPtr());
@@ -203,6 +211,7 @@
 
   // Tests should set these to NULL if they've already triggered their
   // destruction.
+  std::unique_ptr<MockWidgetImpl> widget_impl_;
   RenderWidgetHostImpl* widget_host_;
   RenderWidgetHostViewGuest* view_;
   std::unique_ptr<FakeRendererCompositorFrameSink>
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
index 512716b6..a25656e 100644
--- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -191,6 +191,7 @@
                                widget_delegate,
                                instance->GetProcess(),
                                routing_id,
+                               nullptr,
                                false /* This means: "Is not hidden." */),
                            delegate,
                            main_frame_routing_id,
diff --git a/content/browser/renderer_host/cursor_manager_unittest.cc b/content/browser/renderer_host/cursor_manager_unittest.cc
index 506f7a4..ce61e0d 100644
--- a/content/browser/renderer_host/cursor_manager_unittest.cc
+++ b/content/browser/renderer_host/cursor_manager_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/test/scoped_task_environment.h"
 #include "build/build_config.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -45,6 +46,37 @@
   std::unique_ptr<CursorManager> cursor_manager_;
 };
 
+class MockRenderWidgetHost : public RenderWidgetHostImpl {
+ public:
+  static MockRenderWidgetHost* Create(RenderWidgetHostDelegate* delegate,
+                                      RenderProcessHost* process,
+                                      int32_t routing_id) {
+    mojom::WidgetPtr widget;
+    std::unique_ptr<MockWidgetImpl> widget_impl =
+        base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+
+    return new MockRenderWidgetHost(delegate, process, routing_id,
+                                    std::move(widget_impl), std::move(widget));
+  }
+
+ private:
+  MockRenderWidgetHost(RenderWidgetHostDelegate* delegate,
+                       RenderProcessHost* process,
+                       int routing_id,
+                       std::unique_ptr<MockWidgetImpl> widget_impl,
+                       mojom::WidgetPtr widget)
+      : RenderWidgetHostImpl(delegate,
+                             process,
+                             routing_id,
+                             std::move(widget),
+                             false),
+        widget_impl_(std::move(widget_impl)) {}
+
+  std::unique_ptr<MockWidgetImpl> widget_impl_;
+
+  DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
+};
+
 class CursorManagerTest : public testing::Test {
  public:
   CursorManagerTest()
@@ -61,8 +93,8 @@
 
   RenderWidgetHostImpl* MakeNewWidgetHost() {
     int32_t routing_id = process_host_->GetNextRoutingID();
-    return new RenderWidgetHostImpl(&delegate_, process_host_.get(), routing_id,
-                                    false);
+    return MockRenderWidgetHost::Create(&delegate_, process_host_.get(),
+                                        routing_id);
   }
 
   void TearDown() override {
@@ -192,4 +224,4 @@
 
 }  // namespace content
 
-#endif  // defined(USE_AURA) || defined(OS_MACOSX)
\ No newline at end of file
+#endif  // defined(USE_AURA) || defined(OS_MACOSX)
diff --git a/content/browser/renderer_host/mock_widget_impl.cc b/content/browser/renderer_host/mock_widget_impl.cc
new file mode 100644
index 0000000..a18c954f
--- /dev/null
+++ b/content/browser/renderer_host/mock_widget_impl.cc
@@ -0,0 +1,14 @@
+// Copyright 2017 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 "content/browser/renderer_host/mock_widget_impl.h"
+
+namespace content {
+
+MockWidgetImpl::MockWidgetImpl(mojo::InterfaceRequest<mojom::Widget> request)
+    : binding_(this, std::move(request)) {}
+
+MockWidgetImpl::~MockWidgetImpl() {}
+
+}  // namespace content
diff --git a/content/browser/renderer_host/mock_widget_impl.h b/content/browser/renderer_host/mock_widget_impl.h
new file mode 100644
index 0000000..c289c17
--- /dev/null
+++ b/content/browser/renderer_host/mock_widget_impl.h
@@ -0,0 +1,25 @@
+// Copyright 2017 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 CONTENT_BROWSER_RENDERER_HOST_MOCK_WIDGET_IMPL_H_
+#define CONTENT_BROWSER_RENDERER_HOST_MOCK_WIDGET_IMPL_H_
+
+#include "content/common/widget.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+#include "mojo/public/cpp/bindings/interface_request.h"
+
+namespace content {
+
+class MockWidgetImpl : public mojom::Widget {
+ public:
+  explicit MockWidgetImpl(mojo::InterfaceRequest<mojom::Widget> request);
+  ~MockWidgetImpl() override;
+
+ private:
+  mojo::Binding<mojom::Widget> binding_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_RENDERER_HOST_MOCK_WIDGET_IMPL_H_
diff --git a/content/browser/renderer_host/render_view_host_factory.cc b/content/browser/renderer_host/render_view_host_factory.cc
index 88044399..831b6c7 100644
--- a/content/browser/renderer_host/render_view_host_factory.cc
+++ b/content/browser/renderer_host/render_view_host_factory.cc
@@ -51,7 +51,7 @@
   return new RenderViewHostImpl(
       instance,
       base::MakeUnique<RenderWidgetHostImpl>(
-          widget_delegate, instance->GetProcess(), routing_id, hidden),
+          widget_delegate, instance->GetProcess(), routing_id, nullptr, hidden),
       delegate, main_frame_routing_id, swapped_out,
       true /* has_initialized_audio_host */);
 }
diff --git a/content/browser/renderer_host/render_view_host_unittest.cc b/content/browser/renderer_host/render_view_host_unittest.cc
index 6b13c091..3bebdd6e 100644
--- a/content/browser/renderer_host/render_view_host_unittest.cc
+++ b/content/browser/renderer_host/render_view_host_unittest.cc
@@ -10,6 +10,7 @@
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
 #include "content/browser/frame_host/render_frame_message_filter.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
 #include "content/browser/renderer_host/render_widget_helper.h"
 #include "content/common/frame_messages.h"
@@ -31,15 +32,6 @@
 
 namespace content {
 
-class WidgetImpl : public mojom::Widget {
- public:
-  explicit WidgetImpl(mojo::InterfaceRequest<mojom::Widget> request)
-      : binding_(this, std::move(request)) {}
-
- private:
-  mojo::Binding<mojom::Widget> binding_;
-};
-
 class RenderViewHostTestBrowserClient : public TestContentBrowserClient {
  public:
   RenderViewHostTestBrowserClient() {}
@@ -90,8 +82,8 @@
   int32_t routing_id = process()->GetNextRoutingID();
 
   mojom::WidgetPtr widget;
-  std::unique_ptr<WidgetImpl> widget_impl =
-      base::MakeUnique<WidgetImpl>(mojo::MakeRequest(&widget));
+  std::unique_ptr<MockWidgetImpl> widget_impl =
+      base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
   test_rvh()->CreateNewFullscreenWidget(routing_id, std::move(widget));
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 9d45b34b..48918fe 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -264,6 +264,7 @@
 RenderWidgetHostImpl::RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
                                            RenderProcessHost* process,
                                            int32_t routing_id,
+                                           mojom::WidgetPtr widget,
                                            bool hidden)
     : renderer_initialized_(false),
       destroyed_(false),
@@ -2717,4 +2718,9 @@
   }
 }
 
+void RenderWidgetHostImpl::SetWidget(mojom::WidgetPtr widget) {
+  // TODO(dtapuska): Bind the WidgetInputHandler when that code has
+  // landed. crbug.com/722928
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index fbb69c4..b7b3e81 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -44,6 +44,7 @@
 #include "content/common/input/synthetic_gesture_packet.h"
 #include "content/common/render_widget_surface_properties.h"
 #include "content/common/view_message_enums.h"
+#include "content/common/widget.mojom.h"
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/common/page_zoom.h"
 #include "content/public/common/url_constants.h"
@@ -115,7 +116,9 @@
   RenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
                        RenderProcessHost* process,
                        int32_t routing_id,
+                       mojom::WidgetPtr widget_interface,
                        bool hidden);
+
   ~RenderWidgetHostImpl() override;
 
   // Similar to RenderWidgetHost::FromID, but returning the Impl object.
@@ -589,6 +592,8 @@
   // there are any queued messages belonging to it, they will be processed.
   void DidProcessFrame(uint32_t frame_token);
 
+  void SetWidget(mojom::WidgetPtr widget);
+
  protected:
   // ---------------------------------------------------------------------------
   // The following method is overridden by RenderViewHost to send upwards to
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
index 58c4f0e..6eb6e4b 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router_unittest.cc
@@ -5,6 +5,7 @@
 #include "content/browser/renderer_host/render_widget_host_input_event_router.h"
 
 #include "base/test/scoped_task_environment.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/public/test/mock_render_process_host.h"
 #include "content/public/test/test_browser_context.h"
@@ -81,12 +82,18 @@
         base::MakeUnique<MockRenderProcessHost>(browser_context_.get());
     process_host2_ =
         base::MakeUnique<MockRenderProcessHost>(browser_context_.get());
+    mojom::WidgetPtr widget1;
+    widget_impl1_ =
+        base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget1));
     widget_host1_ = base::MakeUnique<RenderWidgetHostImpl>(
         &delegate_, process_host1_.get(), process_host1_->GetNextRoutingID(),
-        false);
+        std::move(widget1), false);
+    mojom::WidgetPtr widget2;
+    widget_impl2_ =
+        base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget2));
     widget_host2_ = base::MakeUnique<RenderWidgetHostImpl>(
         &delegate_, process_host2_.get(), process_host2_->GetNextRoutingID(),
-        false);
+        std::move(widget2), false);
 
     view_root_ = base::MakeUnique<MockRootRenderWidgetHostView>(
         widget_host1_.get(), frame_sink_id_map_);
@@ -119,7 +126,9 @@
   std::unique_ptr<BrowserContext> browser_context_;
   std::unique_ptr<MockRenderProcessHost> process_host1_;
   std::unique_ptr<MockRenderProcessHost> process_host2_;
+  std::unique_ptr<MockWidgetImpl> widget_impl1_;
   std::unique_ptr<RenderWidgetHostImpl> widget_host1_;
+  std::unique_ptr<MockWidgetImpl> widget_impl2_;
   std::unique_ptr<RenderWidgetHostImpl> widget_host2_;
 
   std::unique_ptr<MockRootRenderWidgetHostView> view_root_;
diff --git a/content/browser/renderer_host/render_widget_host_unittest.cc b/content/browser/renderer_host/render_widget_host_unittest.cc
index 71c668a4..55345c93 100644
--- a/content/browser/renderer_host/render_widget_host_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_unittest.cc
@@ -21,6 +21,7 @@
 #include "build/build_config.h"
 #include "content/browser/gpu/compositor_util.h"
 #include "content/browser/renderer_host/input/legacy_input_router_impl.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_view_host_delegate_view.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -153,17 +154,6 @@
 
 class MockRenderWidgetHost : public RenderWidgetHostImpl {
  public:
-  MockRenderWidgetHost(RenderWidgetHostDelegate* delegate,
-                       RenderProcessHost* process,
-                       int routing_id)
-      : RenderWidgetHostImpl(
-            delegate,
-            process,
-            routing_id,
-            false),
-        new_content_rendering_timeout_fired_(false) {
-    acked_touch_event_type_ = blink::WebInputEvent::kUndefined;
-  }
 
   // Allow poking at a few private members.
   using RenderWidgetHostImpl::GetResizeParams;
@@ -216,6 +206,17 @@
     return processed_frame_messages_count_;
   }
 
+  static MockRenderWidgetHost* Create(RenderWidgetHostDelegate* delegate,
+                                      RenderProcessHost* process,
+                                      int32_t routing_id) {
+    mojom::WidgetPtr widget;
+    std::unique_ptr<MockWidgetImpl> widget_impl =
+        base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+
+    return new MockRenderWidgetHost(delegate, process, routing_id,
+                                    std::move(widget_impl), std::move(widget));
+  }
+
  protected:
   void NotifyNewContentRenderingTimeoutForTesting() override {
     new_content_rendering_timeout_fired_ = true;
@@ -225,10 +226,27 @@
   WebInputEvent::Type acked_touch_event_type_;
 
  private:
+  MockRenderWidgetHost(RenderWidgetHostDelegate* delegate,
+                       RenderProcessHost* process,
+                       int routing_id,
+                       std::unique_ptr<MockWidgetImpl> widget_impl,
+                       mojom::WidgetPtr widget)
+      : RenderWidgetHostImpl(delegate,
+                             process,
+                             routing_id,
+                             std::move(widget),
+                             false),
+        new_content_rendering_timeout_fired_(false),
+        widget_impl_(std::move(widget_impl)) {
+    acked_touch_event_type_ = blink::WebInputEvent::kUndefined;
+  }
+
   void ProcessSwapMessages(std::vector<IPC::Message> messages) override {
     processed_frame_messages_count_++;
   }
   uint32_t processed_frame_messages_count_ = 0;
+  std::unique_ptr<MockWidgetImpl> widget_impl_;
+
   DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHost);
 };
 
@@ -580,8 +598,8 @@
     screen_.reset(aura::TestScreen::Create(gfx::Size()));
     display::Screen::SetScreenInstance(screen_.get());
 #endif
-    host_.reset(new MockRenderWidgetHost(delegate_.get(), process_,
-                                         process_->GetNextRoutingID()));
+    host_.reset(MockRenderWidgetHost::Create(delegate_.get(), process_,
+                                             process_->GetNextRoutingID()));
     view_.reset(new TestView(host_.get()));
     ConfigureView(view_.get());
     host_->SetView(view_.get());
diff --git a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
index e6bcadc..fa9609c 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura_unittest.cc
@@ -44,6 +44,7 @@
 #include "content/browser/renderer_host/delegated_frame_host_client_aura.h"
 #include "content/browser/renderer_host/input/input_router.h"
 #include "content/browser/renderer_host/input/mouse_wheel_event_queue.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/overscroll_controller.h"
 #include "content/browser/renderer_host/overscroll_controller_delegate.h"
 #include "content/browser/renderer_host/render_view_host_factory.h"
@@ -553,13 +554,7 @@
 
 class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
  public:
-  MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
-                           RenderProcessHost* process,
-                           int32_t routing_id)
-      : RenderWidgetHostImpl(delegate, process, routing_id, false) {
-    set_renderer_initialized(true);
-    lastWheelOrTouchEventLatencyInfo = ui::LatencyInfo();
-  }
+  ~MockRenderWidgetHostImpl() override {}
 
   // Extracts |latency_info| for wheel event, and stores it in
   // |lastWheelOrTouchEventLatencyInfo|.
@@ -581,7 +576,35 @@
     lastWheelOrTouchEventLatencyInfo = ui::LatencyInfo(ui_latency);
   }
 
+  static MockRenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate,
+                                          RenderProcessHost* process,
+                                          int32_t routing_id) {
+    mojom::WidgetPtr widget;
+    std::unique_ptr<MockWidgetImpl> widget_impl =
+        base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+
+    return new MockRenderWidgetHostImpl(delegate, process, routing_id,
+                                        std::move(widget_impl),
+                                        std::move(widget));
+  }
   ui::LatencyInfo lastWheelOrTouchEventLatencyInfo;
+
+ private:
+  MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
+                           RenderProcessHost* process,
+                           int32_t routing_id,
+                           std::unique_ptr<MockWidgetImpl> widget_impl,
+                           mojom::WidgetPtr widget)
+      : RenderWidgetHostImpl(delegate,
+                             process,
+                             routing_id,
+                             std::move(widget),
+                             false),
+        widget_impl_(std::move(widget_impl)) {
+    lastWheelOrTouchEventLatencyInfo = ui::LatencyInfo();
+  }
+
+  std::unique_ptr<MockWidgetImpl> widget_impl_;
 };
 
 const WebInputEvent* GetInputEventFromMessage(const IPC::Message& message) {
@@ -632,8 +655,8 @@
 
     int32_t routing_id = process_host_->GetNextRoutingID();
     delegates_.push_back(base::WrapUnique(new MockRenderWidgetHostDelegate));
-    parent_host_ = new RenderWidgetHostImpl(delegates_.back().get(),
-                                            process_host_, routing_id, false);
+    parent_host_ = MockRenderWidgetHostImpl::Create(delegates_.back().get(),
+                                                    process_host_, routing_id);
     delegates_.back()->set_widget_host(parent_host_);
     parent_view_ =
         new RenderWidgetHostViewAura(parent_host_, is_guest_view_hack_);
@@ -644,8 +667,8 @@
 
     routing_id = process_host_->GetNextRoutingID();
     delegates_.push_back(base::WrapUnique(new MockRenderWidgetHostDelegate));
-    widget_host_ = new MockRenderWidgetHostImpl(delegates_.back().get(),
-                                                process_host_, routing_id);
+    widget_host_ = MockRenderWidgetHostImpl::Create(delegates_.back().get(),
+                                                    process_host_, routing_id);
     delegates_.back()->set_widget_host(widget_host_);
     widget_host_->Init();
     view_ = new FakeRenderWidgetHostViewAura(widget_host_, is_guest_view_hack_);
@@ -3108,8 +3131,8 @@
   for (size_t i = 0; i < renderer_count; ++i) {
     int32_t routing_id = process_host_->GetNextRoutingID();
     delegates_.push_back(base::WrapUnique(new MockRenderWidgetHostDelegate));
-    hosts[i] = new RenderWidgetHostImpl(delegates_.back().get(), process_host_,
-                                        routing_id, false);
+    hosts[i] = MockRenderWidgetHostImpl::Create(delegates_.back().get(),
+                                                process_host_, routing_id);
     delegates_.back()->set_widget_host(hosts[i]);
     hosts[i]->Init();
     views[i] = new FakeRenderWidgetHostViewAura(hosts[i], false);
@@ -3282,8 +3305,8 @@
   for (size_t i = 0; i < renderer_count; ++i) {
     int32_t routing_id = process_host_->GetNextRoutingID();
     delegates_.push_back(base::WrapUnique(new MockRenderWidgetHostDelegate));
-    hosts[i] = new RenderWidgetHostImpl(delegates_.back().get(), process_host_,
-                                        routing_id, false);
+    hosts[i] = MockRenderWidgetHostImpl::Create(delegates_.back().get(),
+                                                process_host_, routing_id);
     delegates_.back()->set_widget_host(hosts[i]);
     hosts[i]->Init();
     views[i] = new FakeRenderWidgetHostViewAura(hosts[i], false);
@@ -3354,9 +3377,10 @@
   // Create a bunch of renderers.
   for (size_t i = 0; i < renderer_count; ++i) {
     int32_t routing_id = process_host_->GetNextRoutingID();
+
     delegates_.push_back(base::WrapUnique(new MockRenderWidgetHostDelegate));
-    hosts[i] = new RenderWidgetHostImpl(delegates_.back().get(), process_host_,
-                                        routing_id, false);
+    hosts[i] = MockRenderWidgetHostImpl::Create(delegates_.back().get(),
+                                                process_host_, routing_id);
     delegates_.back()->set_widget_host(hosts[i]);
     hosts[i]->Init();
     views[i] = new FakeRenderWidgetHostViewAura(hosts[i], false);
@@ -5888,10 +5912,11 @@
     return process_host;
   }
 
-  RenderWidgetHostImpl* CreateRenderWidgetHostForProcess(
+  MockRenderWidgetHostImpl* CreateRenderWidgetHostForProcess(
       MockRenderProcessHost* process_host) {
-    return new RenderWidgetHostImpl(render_widget_host_delegate(), process_host,
-                                    process_host->GetNextRoutingID(), false);
+    return MockRenderWidgetHostImpl::Create(render_widget_host_delegate(),
+                                            process_host,
+                                            process_host->GetNextRoutingID());
   }
 
   TestRenderWidgetHostView* CreateViewForProcess(
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
index b24bdafb..ce453723 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_editcommand_helper_unittest.mm
@@ -14,6 +14,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
 #include "content/browser/gpu/compositor_util.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/common/input_messages.h"
@@ -140,9 +141,12 @@
   base::mac::ScopedNSAutoreleasePool pool;
 
   int32_t routing_id = process_host->GetNextRoutingID();
+  mojom::WidgetPtr widget;
+  std::unique_ptr<MockWidgetImpl> widget_impl =
+      base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
 
-  RenderWidgetHostImpl* render_widget =
-      new RenderWidgetHostImpl(&delegate, process_host, routing_id, false);
+  RenderWidgetHostImpl* render_widget = new RenderWidgetHostImpl(
+      &delegate, process_host, routing_id, std::move(widget), false);
 
   ui::WindowResizeHelperMac::Get()->Init(base::ThreadTaskRunnerHandle::Get());
 
diff --git a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
index ef72d17..01bb2ce 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac_unittest.mm
@@ -24,6 +24,7 @@
 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
 #include "content/browser/frame_host/render_widget_host_view_guest.h"
 #include "content/browser/gpu/compositor_util.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
 #include "content/browser/renderer_host/text_input_manager.h"
 #include "content/common/input_messages.h"
@@ -236,13 +237,7 @@
 
 class MockRenderWidgetHostImpl : public RenderWidgetHostImpl {
  public:
-  MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
-                           RenderProcessHost* process,
-                           int32_t routing_id)
-      : RenderWidgetHostImpl(delegate, process, routing_id, false) {
-    set_renderer_initialized(true);
-    lastWheelEventLatencyInfo = ui::LatencyInfo();
-  }
+  ~MockRenderWidgetHostImpl() override {}
 
   // Extracts |latency_info| and stores it in |lastWheelEventLatencyInfo|.
   void ForwardWheelEventWithLatencyInfo (
@@ -257,8 +252,36 @@
   MOCK_METHOD0(Blur, void());
 
   ui::LatencyInfo lastWheelEventLatencyInfo;
+  static MockRenderWidgetHostImpl* Create(RenderWidgetHostDelegate* delegate,
+                                          RenderProcessHost* process,
+                                          int32_t routing_id) {
+    mojom::WidgetPtr widget;
+    std::unique_ptr<MockWidgetImpl> widget_impl =
+        base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+
+    return new MockRenderWidgetHostImpl(delegate, process, routing_id,
+                                        std::move(widget_impl),
+                                        std::move(widget));
+  }
 
  private:
+  MockRenderWidgetHostImpl(RenderWidgetHostDelegate* delegate,
+                           RenderProcessHost* process,
+                           int32_t routing_id,
+                           std::unique_ptr<MockWidgetImpl> widget_impl,
+                           mojom::WidgetPtr widget)
+      : RenderWidgetHostImpl(delegate,
+                             process,
+                             routing_id,
+                             std::move(widget),
+                             false),
+        widget_impl_(std::move(widget_impl)) {
+    set_renderer_initialized(true);
+    lastWheelEventLatencyInfo = ui::LatencyInfo();
+  }
+
+  std::unique_ptr<MockWidgetImpl> widget_impl_;
+
   DISALLOW_COPY_AND_ASSIGN(MockRenderWidgetHostImpl);
 };
 
@@ -460,8 +483,8 @@
       new MockRenderProcessHost(&browser_context);
   int32_t routing_id = process_host->GetNextRoutingID();
   // Owned by its |cocoa_view()|.
-  RenderWidgetHostImpl* rwh =
-      new RenderWidgetHostImpl(&delegate, process_host, routing_id, false);
+  MockRenderWidgetHostImpl* rwh =
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false);
 
   view->InitAsFullscreen(rwhv_mac_);
@@ -494,8 +517,8 @@
       new MockRenderProcessHost(&browser_context);
   int32_t routing_id = process_host->GetNextRoutingID();
   // Owned by its |cocoa_view()|.
-  RenderWidgetHostImpl* rwh =
-      new RenderWidgetHostImpl(&delegate, process_host, routing_id, false);
+  MockRenderWidgetHostImpl* rwh =
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false);
 
   view->InitAsFullscreen(rwhv_mac_);
@@ -527,7 +550,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
 
   // Simulate ctrl+F12, will produce a private use character but shouldn't
@@ -573,7 +596,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
 
   // Simulate "Convert" key on JIS PC keyboard, will generate a |NSFlagsChanged|
@@ -954,7 +977,7 @@
   // Owned by its |cocoa_view()|.
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* rwh =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false);
 
   base::scoped_nsobject<CocoaTestHelperWindow> window(
@@ -998,7 +1021,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1036,7 +1059,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1062,7 +1085,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1105,7 +1128,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1140,7 +1163,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1175,7 +1198,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1204,7 +1227,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1269,7 +1292,7 @@
 
   // Owned by its |cocoa_view()|.
   MockRenderWidgetHostImpl* rwh =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, true);
 
   // Add a delegate to the view.
@@ -1311,7 +1334,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
 
   EXPECT_EQ(static_cast<unsigned>(SK_ColorTRANSPARENT),
@@ -1373,7 +1396,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1420,7 +1443,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1477,7 +1500,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1537,8 +1560,8 @@
     process_host_->Init();
     delegate_.reset(new MockRenderWidgetHostDelegate);
     int32_t routing_id = process_host_->GetNextRoutingID();
-    host_.reset(new MockRenderWidgetHostImpl(delegate_.get(),
-                                             process_host_.get(), routing_id));
+    host_.reset(MockRenderWidgetHostImpl::Create(
+        delegate_.get(), process_host_.get(), routing_id));
     view_ = new RenderWidgetHostViewMac(host_.get(), false);
     cocoa_view_.reset([view_->cocoa_view() retain]);
     process_host_->sink().ClearMessages();
@@ -1724,7 +1747,7 @@
   MockRenderWidgetHostDelegate delegate;
   int32_t routing_id = process_host->GetNextRoutingID();
   MockRenderWidgetHostImpl* host =
-      new MockRenderWidgetHostImpl(&delegate, process_host, routing_id);
+      MockRenderWidgetHostImpl::Create(&delegate, process_host, routing_id);
   RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false);
   process_host->sink().ClearMessages();
 
@@ -1774,9 +1797,9 @@
     child_process_host_ = new MockRenderProcessHost(&browser_context_);
     RenderWidgetHostDelegate* rwh_delegate =
         RenderWidgetHostImpl::From(rvh()->GetWidget())->delegate();
-    child_widget_ = new RenderWidgetHostImpl(
+    child_widget_ = MockRenderWidgetHostImpl::Create(
         rwh_delegate, child_process_host_,
-        child_process_host_->GetNextRoutingID(), false);
+        child_process_host_->GetNextRoutingID());
     child_view_ = new TestRenderWidgetHostView(child_widget_);
     text_input_manager_ = rwh_delegate->GetTextInputManager();
     tab_widget_ = RenderWidgetHostImpl::From(rvh()->GetWidget());
diff --git a/content/browser/renderer_host/text_input_client_mac_unittest.mm b/content/browser/renderer_host/text_input_client_mac_unittest.mm
index 73c1be83..e8cee18 100644
--- a/content/browser/renderer_host/text_input_client_mac_unittest.mm
+++ b/content/browser/renderer_host/text_input_client_mac_unittest.mm
@@ -12,6 +12,7 @@
 #include "base/single_thread_task_runner.h"
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread.h"
+#include "content/browser/renderer_host/mock_widget_impl.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_delegate.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -58,7 +59,12 @@
     RenderProcessHost* rph =
         process_factory_.CreateRenderProcessHost(&browser_context_);
     int32_t routing_id = rph->GetNextRoutingID();
-    widget_.reset(new RenderWidgetHostImpl(&delegate_, rph, routing_id, false));
+    mojom::WidgetPtr widget;
+    mock_widget_impl_ =
+        base::MakeUnique<MockWidgetImpl>(mojo::MakeRequest(&widget));
+
+    widget_.reset(new RenderWidgetHostImpl(&delegate_, rph, routing_id,
+                                           std::move(widget), false));
   }
 
   void TearDown() override {
@@ -106,6 +112,7 @@
   MockRenderProcessHostFactory process_factory_;
   MockRenderWidgetHostDelegate delegate_;
   std::unique_ptr<RenderWidgetHostImpl> widget_;
+  std::unique_ptr<MockWidgetImpl> mock_widget_impl_;
 
   base::Thread thread_;
 };
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 67cffc5..0eed782 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1713,10 +1713,9 @@
         site_instance->GetProcess()->GetNextRoutingID();
   }
 
-  GetRenderManager()->Init(site_instance.get(), view_routing_id,
-                           params.main_frame_routing_id,
-                           main_frame_widget_routing_id,
-                           params.renderer_initiated_creation);
+  GetRenderManager()->Init(
+      site_instance.get(), view_routing_id, params.main_frame_routing_id,
+      main_frame_widget_routing_id, params.renderer_initiated_creation);
 
   // blink::FrameTree::setName always keeps |unique_name| empty in case of a
   // main frame - let's do the same thing here.
@@ -2421,8 +2420,8 @@
     return;
   }
 
-  RenderWidgetHostImpl* widget_host =
-      new RenderWidgetHostImpl(this, process, route_id, IsHidden());
+  RenderWidgetHostImpl* widget_host = new RenderWidgetHostImpl(
+      this, process, route_id, std::move(widget), IsHidden());
 
   RenderWidgetHostViewBase* widget_view =
       static_cast<RenderWidgetHostViewBase*>(
diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc
index baa3bc9f..e5b7da6 100644
--- a/content/renderer/render_frame_impl.cc
+++ b/content/renderer/render_frame_impl.cc
@@ -6766,6 +6766,9 @@
   registry_.AddInterface(base::Bind(&FrameInputHandlerImpl::CreateMojoService,
                                     weak_factory_.GetWeakPtr()));
 
+  registry_.AddInterface(
+      base::Bind(&RenderFrameImpl::BindWidget, weak_factory_.GetWeakPtr()));
+
   if (!frame_->Parent()) {
     // Only main frame have ImageDownloader service.
     registry_.AddInterface(base::Bind(&ImageDownloaderImpl::CreateMojoService,
@@ -7108,4 +7111,8 @@
       form(info.form),
       source_location(info.source_location) {}
 
+void RenderFrameImpl::BindWidget(mojom::WidgetRequest request) {
+  GetRenderWidget()->SetWidgetBinding(std::move(request));
+}
+
 }  // namespace content
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h
index 0dcf3ac..88ca1d1 100644
--- a/content/renderer/render_frame_impl.h
+++ b/content/renderer/render_frame_impl.h
@@ -36,6 +36,7 @@
 #include "content/common/host_zoom.mojom.h"
 #include "content/common/renderer.mojom.h"
 #include "content/common/unique_name_helper.h"
+#include "content/common/widget.mojom.h"
 #include "content/public/common/console_message_level.h"
 #include "content/public/common/javascript_dialog_type.h"
 #include "content/public/common/previews_state.h"
@@ -1177,6 +1178,7 @@
 
   void UpdatePeakMemoryStats();
   void ReportPeakMemoryStats();
+  void BindWidget(mojom::WidgetRequest request);
 
   // Stores the WebLocalFrame we are associated with.  This is null from the
   // constructor until BindToFrame() is called, and it is null after
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index c0f66e7..883d81d 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -2410,4 +2410,11 @@
       ->GetActiveWebInputMethodController();
 }
 
+void RenderWidget::SetWidgetBinding(mojom::WidgetRequest request) {
+  // Close the old binding if there was one.
+  // A RenderWidgetHost should not need more than one channel.
+  widget_binding_.Close();
+  widget_binding_.Bind(std::move(request));
+}
+
 }  // namespace content
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h
index b7ce5d32..5871433 100644
--- a/content/renderer/render_widget.h
+++ b/content/renderer/render_widget.h
@@ -464,6 +464,7 @@
   // composition info (when in monitor mode).
   void OnRequestCompositionUpdates(bool immediate_request,
                                    bool monitor_updates);
+  void SetWidgetBinding(mojom::WidgetRequest request);
 
  protected:
   // Friend RefCounted so that the dtor can be non-public. Using this class
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 73bcaf8f..c5bbeaea 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1307,6 +1307,8 @@
     "../browser/renderer_host/media/video_capture_controller_unittest.cc",
     "../browser/renderer_host/media/video_capture_manager_unittest.cc",
     "../browser/renderer_host/media/video_capture_unittest.cc",
+    "../browser/renderer_host/mock_widget_impl.cc",
+    "../browser/renderer_host/mock_widget_impl.h",
     "../browser/renderer_host/offscreen_canvas_provider_impl_unittest.cc",
     "../browser/renderer_host/render_process_host_unittest.cc",
     "../browser/renderer_host/render_view_host_unittest.cc",
diff --git a/content/test/test_render_view_host_factory.cc b/content/test/test_render_view_host_factory.cc
index 6732547..32981f5 100644
--- a/content/test/test_render_view_host_factory.cc
+++ b/content/test/test_render_view_host_factory.cc
@@ -38,7 +38,7 @@
   return new TestRenderViewHost(instance,
                                 base::MakeUnique<RenderWidgetHostImpl>(
                                     widget_delegate, instance->GetProcess(),
-                                    routing_id, false /* hidden */),
+                                    routing_id, nullptr, false /* hidden */),
                                 delegate, main_frame_routing_id, swapped_out);
 }