Refactors event dispatching of NativeViewport into its own interface

This way the WindowManager can handle the event directly. New flow is
for the ViewManager to request the NativeViewportEventDispatcher from
the WindowManager and connect said NativeViewportEventDispatcher to
the NativeViewport.

BUG=none
TEST=none
R=ben@chromium.org

Review URL: https://codereview.chromium.org/685013002
diff --git a/examples/sample_app/sample_app.cc b/examples/sample_app/sample_app.cc
index 26eac51..afc80fa 100644
--- a/examples/sample_app/sample_app.cc
+++ b/examples/sample_app/sample_app.cc
@@ -21,20 +21,24 @@
 
 namespace examples {
 
-class SampleApp : public mojo::ApplicationDelegate,
-                  public mojo::NativeViewportClient {
+class SampleApp
+    : public mojo::ApplicationDelegate,
+      public mojo::NativeViewportClient,
+      public mojo::InterfaceImpl<mojo::NativeViewportEventDispatcher> {
  public:
   SampleApp() : weak_factory_(this) {}
 
-  virtual ~SampleApp() {
+  ~SampleApp() override {
     // TODO(darin): Fix shutdown so we don't need to leak this.
     mojo_ignore_result(gles2_client_.release());
   }
 
-  virtual void Initialize(mojo::ApplicationImpl* app) override {
+  void Initialize(mojo::ApplicationImpl* app) override {
     app->ConnectToService("mojo:native_viewport_service", &viewport_);
     viewport_.set_client(this);
 
+    SetEventDispatcher();
+
     // TODO(jamesr): Should be mojo:gpu_service
     app->ConnectToService("mojo:native_viewport_service", &gpu_service_);
 
@@ -47,16 +51,16 @@
     viewport_->Show();
   }
 
-  virtual void OnDestroyed() override { mojo::RunLoop::current()->Quit(); }
+  void OnDestroyed() override { mojo::RunLoop::current()->Quit(); }
 
-  virtual void OnSizeChanged(mojo::SizePtr size) override {
+  void OnSizeChanged(mojo::SizePtr size) override {
     assert(size);
     if (gles2_client_)
       gles2_client_->SetSize(*size);
   }
 
-  virtual void OnEvent(mojo::EventPtr event,
-                       const mojo::Callback<void()>& callback) override {
+  void OnEvent(mojo::EventPtr event,
+               const mojo::Callback<void()>& callback) override {
     assert(event);
     if (event->location_data && event->location_data->in_view_location)
       gles2_client_->HandleInputEvent(*event);
@@ -64,6 +68,12 @@
   }
 
  private:
+  void SetEventDispatcher() {
+    mojo::NativeViewportEventDispatcherPtr proxy;
+    mojo::WeakBindToProxy(this, &proxy);
+    viewport_->SetEventDispatcher(proxy.Pass());
+  }
+
   void OnCreatedNativeViewport(uint64_t native_viewport_id) {
     mojo::SizePtr size = mojo::Size::New();
     size->width = 800;
diff --git a/examples/surfaces_app/surfaces_app.cc b/examples/surfaces_app/surfaces_app.cc
index 1dd8bc2..4331654 100644
--- a/examples/surfaces_app/surfaces_app.cc
+++ b/examples/surfaces_app/surfaces_app.cc
@@ -105,10 +105,6 @@
   // NativeViewportClient implementation.
   virtual void OnSizeChanged(mojo::SizePtr size) override {}
   virtual void OnDestroyed() override {}
-  virtual void OnEvent(mojo::EventPtr event,
-                       const mojo::Callback<void()>& callback) override {
-    callback.Run();
-  }
 
  private:
   void OnCreatedNativeViewport(uint64_t native_viewport_id) {}
diff --git a/mojo/services/native_viewport/native_viewport_impl.cc b/mojo/services/native_viewport/native_viewport_impl.cc
index 810d339..d6c39d5 100644
--- a/mojo/services/native_viewport/native_viewport_impl.cc
+++ b/mojo/services/native_viewport/native_viewport_impl.cc
@@ -93,6 +93,11 @@
     viewport_surface_->SetChildId(child_surface_id_);
 }
 
+void NativeViewportImpl::SetEventDispatcher(
+    NativeViewportEventDispatcherPtr dispatcher) {
+  event_dispatcher_ = dispatcher.Pass();
+}
+
 void NativeViewportImpl::OnBoundsChanged(const gfx::Rect& bounds) {
   if (size_ == bounds.size())
     return;
@@ -118,6 +123,9 @@
 }
 
 bool NativeViewportImpl::OnEvent(ui::Event* ui_event) {
+  if (!event_dispatcher_.get())
+    return false;
+
   // Must not return early before updating capture.
   switch (ui_event->type()) {
     case ui::ET_MOUSE_PRESSED:
@@ -135,7 +143,7 @@
   if (waiting_for_event_ack_ && IsRateLimitedEventType(ui_event))
     return false;
 
-  client()->OnEvent(
+  event_dispatcher_->OnEvent(
       Event::From(*ui_event),
       base::Bind(&NativeViewportImpl::AckEvent, weak_factory_.GetWeakPtr()));
   waiting_for_event_ack_ = true;
diff --git a/mojo/services/native_viewport/native_viewport_impl.h b/mojo/services/native_viewport/native_viewport_impl.h
index d63b0f7..e0e37a9 100644
--- a/mojo/services/native_viewport/native_viewport_impl.h
+++ b/mojo/services/native_viewport/native_viewport_impl.h
@@ -35,6 +35,7 @@
   void Close() override;
   void SetSize(SizePtr size) override;
   void SubmittedFrame(SurfaceIdPtr surface_id) override;
+  void SetEventDispatcher(NativeViewportEventDispatcherPtr dispatcher) override;
 
   // PlatformViewport::Delegate implementation.
   void OnBoundsChanged(const gfx::Rect& bounds) override;
@@ -57,6 +58,7 @@
   cc::SurfaceId child_surface_id_;
   bool waiting_for_event_ack_;
   Callback<void(uint64_t)> create_callback_;
+  NativeViewportEventDispatcherPtr event_dispatcher_;
   base::WeakPtrFactory<NativeViewportImpl> weak_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(NativeViewportImpl);
diff --git a/mojo/services/public/interfaces/native_viewport/native_viewport.mojom b/mojo/services/public/interfaces/native_viewport/native_viewport.mojom
index 61e32e7..3d20ff4 100644
--- a/mojo/services/public/interfaces/native_viewport/native_viewport.mojom
+++ b/mojo/services/public/interfaces/native_viewport/native_viewport.mojom
@@ -19,6 +19,11 @@
   Close();
   SetSize(Size size);
   SubmittedFrame(SurfaceId surface_id);
+  SetEventDispatcher(NativeViewportEventDispatcher dispatcher);
+};
+
+interface NativeViewportEventDispatcher {
+  OnEvent(Event event) => ();
 };
 
 interface NativeViewportClient {
@@ -26,7 +31,6 @@
   // called.
   OnSizeChanged(Size size);
   OnDestroyed();
-  OnEvent(Event event) => ();
 };
 
 }
diff --git a/mojo/services/public/interfaces/window_manager/window_manager_internal.mojom b/mojo/services/public/interfaces/window_manager/window_manager_internal.mojom
index 9d7fef1..0ad089b 100644
--- a/mojo/services/public/interfaces/window_manager/window_manager_internal.mojom
+++ b/mojo/services/public/interfaces/window_manager/window_manager_internal.mojom
@@ -6,23 +6,8 @@
 
 module mojo {
 
-// WindowManagerInternalService provides high level window management policies
-// and is used by the ViewManager. This interface is marked as internal as only
-// the view manager is allowed to connect to this.
-[Client=WindowManagerInternalClient]
-interface WindowManagerInternalService {
-  // Called when an input event is received from the native system. It's
-  // expected that when this is received the WindowManagerInternalService will
-  // call back to WindowManagerInternalServieClient will call
-  // DispatchInputEventToView().
-  // TODO(sky): nuke this and instead have an interface specifically for
-  // dispatching events in the NativeViewportService.
-  OnViewInputEvent(mojo.Event event);
-};
-
-// ViewManager provides this interface for functionality only exposed to the
-// WindowManagerInternalServie.
-[Client=WindowManagerInternalService]
+// ViewManager provides this interface to the WindowManager. It enables
+// capabilities specific to the WindowManager.
 interface WindowManagerInternalClient {
   // Dispatches the specified input event to the specified view.
   DispatchInputEventToView(uint32 view_id, mojo.Event event);
diff --git a/mojo/services/view_manager/connection_manager.cc b/mojo/services/view_manager/connection_manager.cc
index 253cc76..120e491 100644
--- a/mojo/services/view_manager/connection_manager.cc
+++ b/mojo/services/view_manager/connection_manager.cc
@@ -15,6 +15,29 @@
 namespace mojo {
 namespace service {
 
+class WindowManagerInternalClientImpl
+    : public InterfaceImpl<WindowManagerInternalClient> {
+ public:
+  WindowManagerInternalClientImpl(WindowManagerInternalClient* real_client,
+                                  ErrorHandler* error_handler)
+      : real_client_(real_client), error_handler_(error_handler) {}
+  ~WindowManagerInternalClientImpl() override {}
+
+  // WindowManagerInternalClient:
+  void DispatchInputEventToView(Id transport_view_id, EventPtr event) override {
+    real_client_->DispatchInputEventToView(transport_view_id, event.Pass());
+  }
+
+  // InterfaceImpl:
+  void OnConnectionError() override { error_handler_->OnConnectionError(); }
+
+ private:
+  WindowManagerInternalClient* real_client_;
+  ErrorHandler* error_handler_;
+
+  DISALLOW_COPY_AND_ASSIGN(WindowManagerInternalClientImpl);
+};
+
 ConnectionManager::ScopedChange::ScopedChange(
     ViewManagerServiceImpl* connection,
     ConnectionManager* connection_manager,
@@ -43,12 +66,12 @@
       root_(new ServerView(this, RootViewId())),
       current_change_(NULL),
       in_destructor_(false) {
-  app_connection->ConnectToService(&window_manager_);
-  window_manager_.set_client(this);
-  window_manager_.set_error_handler(this);
   // |app_connection| originates from the WindowManager. Let it connect
-  // directly to the ViewManager.
-  app_connection->AddService(this);
+  // directly to the ViewManager and WindowManagerInternalClient.
+  app_connection->AddService(
+      static_cast<InterfaceFactory<ViewManagerService>*>(this));
+  app_connection->AddService(
+      static_cast<InterfaceFactory<WindowManagerInternalClient>*>(this));
   root_->SetBounds(gfx::Rect(800, 600));
 }
 
@@ -149,10 +172,6 @@
   return NULL;
 }
 
-void ConnectionManager::DispatchViewInputEventToDelegate(EventPtr event) {
-  window_manager_->OnViewInputEvent(event.Pass());
-}
-
 void ConnectionManager::ProcessViewBoundsChanged(const ServerView* view,
                                                  const gfx::Rect& old_bounds,
                                                  const gfx::Rect& new_bounds) {
@@ -336,6 +355,19 @@
   WeakBindToRequest(window_manager_vm_service_, &request);
 }
 
+void ConnectionManager::Create(
+    ApplicationConnection* connection,
+    InterfaceRequest<WindowManagerInternalClient> request) {
+  if (wm_internal_client_impl_.get()) {
+    VLOG(1) << "WindowManagerInternalClient requested more than once.";
+    return;
+  }
+
+  wm_internal_client_impl_.reset(
+      new WindowManagerInternalClientImpl(this, this));
+  WeakBindToRequest(wm_internal_client_impl_.get(), &request);
+}
+
 void ConnectionManager::OnConnectionError() {
   delegate_->OnLostConnectionToWindowManager();
 }
diff --git a/mojo/services/view_manager/connection_manager.h b/mojo/services/view_manager/connection_manager.h
index 99a772d..0a41195 100644
--- a/mojo/services/view_manager/connection_manager.h
+++ b/mojo/services/view_manager/connection_manager.h
@@ -28,6 +28,7 @@
 
 class ConnectionManagerDelegate;
 class ViewManagerServiceImpl;
+class WindowManagerInternalClientImpl;
 
 // ConnectionManager manages the set of connections to the ViewManager (all the
 // ViewManagerServiceImpls) as well as providing the root of the hierarchy.
@@ -35,6 +36,7 @@
     : public ServerViewDelegate,
       public WindowManagerInternalClient,
       public InterfaceFactory<ViewManagerService>,
+      public InterfaceFactory<WindowManagerInternalClient>,
       public ErrorHandler {
  public:
   // Create when a ViewManagerServiceImpl is about to make a change. Ensures
@@ -115,8 +117,6 @@
   }
   const ViewManagerServiceImpl* GetConnectionWithRoot(const ViewId& id) const;
 
-  void DispatchViewInputEventToDelegate(EventPtr event);
-
   // These functions trivially delegate to all ViewManagerServiceImpls, which in
   // term notify their clients.
   void ProcessViewDestroyed(ServerView* view);
@@ -184,6 +184,11 @@
   virtual void Create(ApplicationConnection* connection,
                       InterfaceRequest<ViewManagerService> request) override;
 
+  // InterfaceFactory<WindowManagerInternalClient>:
+  virtual void Create(
+      ApplicationConnection* connection,
+      InterfaceRequest<WindowManagerInternalClient> request) override;
+
   // ErrorHandler:
   void OnConnectionError() override;
 
@@ -196,8 +201,6 @@
   // NOTE: |window_manager_vm_service_| is also in |connection_map_|.
   ViewManagerServiceImpl* window_manager_vm_service_;
 
-  WindowManagerInternalServicePtr window_manager_;
-
   // ID to use for next ViewManagerServiceImpl.
   ConnectionSpecificId next_connection_id_;
 
@@ -208,6 +211,8 @@
 
   scoped_ptr<ServerView> root_;
 
+  scoped_ptr<WindowManagerInternalClientImpl> wm_internal_client_impl_;
+
   // If non-null we're processing a change. The ScopedChange is not owned by us
   // (it's created on the stack by ViewManagerServiceImpl).
   ScopedChange* current_change_;
diff --git a/mojo/services/view_manager/display_manager.cc b/mojo/services/view_manager/display_manager.cc
index 4891d9b..fa91e2d 100644
--- a/mojo/services/view_manager/display_manager.cc
+++ b/mojo/services/view_manager/display_manager.cc
@@ -88,6 +88,10 @@
   app_connection->ConnectToService("mojo:surfaces_service", &surfaces_service_);
   surfaces_service_->CreateSurfaceConnection(base::Bind(
       &DisplayManager::OnSurfaceConnectionCreated, weak_factory_.GetWeakPtr()));
+
+  NativeViewportEventDispatcherPtr event_dispatcher;
+  app_connection->ConnectToService(&event_dispatcher);
+  native_viewport_->SetEventDispatcher(event_dispatcher.Pass());
 }
 
 DisplayManager::~DisplayManager() {
@@ -160,12 +164,6 @@
   SchedulePaint(connection_manager_->root(), gfx::Rect(size_));
 }
 
-void DisplayManager::OnEvent(EventPtr event,
-                             const mojo::Callback<void()>& callback) {
-  connection_manager_->DispatchViewInputEventToDelegate(event.Pass());
-  callback.Run();
-}
-
 void DisplayManager::ReturnResources(Array<ReturnedResourcePtr> resources) {
   DCHECK_EQ(0u, resources.size());
 }
diff --git a/mojo/services/view_manager/display_manager.h b/mojo/services/view_manager/display_manager.h
index 1f5f930..09e6bfc 100644
--- a/mojo/services/view_manager/display_manager.h
+++ b/mojo/services/view_manager/display_manager.h
@@ -56,7 +56,6 @@
   // NativeViewportClient implementation.
   void OnDestroyed() override;
   void OnSizeChanged(SizePtr size) override;
-  void OnEvent(EventPtr event, const mojo::Callback<void()>& callback) override;
 
   // SurfaceClient implementation.
   void ReturnResources(Array<ReturnedResourcePtr> resources) override;
diff --git a/mojo/services/view_manager/view_manager_unittest.cc b/mojo/services/view_manager/view_manager_unittest.cc
index 1188a7f..27d94ec 100644
--- a/mojo/services/view_manager/view_manager_unittest.cc
+++ b/mojo/services/view_manager/view_manager_unittest.cc
@@ -251,7 +251,7 @@
 
  private:
   friend class TestViewManagerClientConnection;
-  friend class WindowManagerInternalServiceImpl;
+  friend class TestWindowManagerImpl;
 
   void set_router(mojo::internal::Router* router) { router_ = router; }
 
@@ -407,36 +407,13 @@
   DISALLOW_COPY_AND_ASSIGN(TestViewManagerClientConnection);
 };
 
-class WindowManagerInternalServiceImpl
-    : public InterfaceImpl<WindowManagerInternalService> {
- public:
-  explicit WindowManagerInternalServiceImpl(
-      TestViewManagerClientConnection* connection)
-      : connection_(connection) {}
-  ~WindowManagerInternalServiceImpl() override {}
-
-  // InterfaceImpl:
-  void OnConnectionEstablished() override {
-    connection_->proxy()->set_window_manager_client(client());
-  }
-
-  void OnViewInputEvent(mojo::EventPtr event) override {}
-
- private:
-  TestViewManagerClientConnection* connection_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerInternalServiceImpl);
-};
-
 // Used with ViewManagerService::Embed(). Creates a
 // TestViewManagerClientConnection, which creates and owns the ViewManagerProxy.
-class EmbedApplicationLoader
-    : public ApplicationLoader,
-      ApplicationDelegate,
-      public InterfaceFactory<ViewManagerClient>,
-      public InterfaceFactory<WindowManagerInternalService> {
+class EmbedApplicationLoader : public ApplicationLoader,
+                               ApplicationDelegate,
+                               public InterfaceFactory<ViewManagerClient> {
  public:
-  EmbedApplicationLoader() : last_view_manager_client_(nullptr) {}
+  EmbedApplicationLoader() {}
   ~EmbedApplicationLoader() override {}
 
   // ApplicationLoader implementation:
@@ -456,46 +433,35 @@
   // ApplicationDelegate implementation:
   bool ConfigureIncomingConnection(ApplicationConnection* connection) override {
     connection->AddService<ViewManagerClient>(this);
-    connection->AddService<WindowManagerInternalService>(this);
     return true;
   }
 
   // InterfaceFactory<ViewManagerClient> implementation:
   void Create(ApplicationConnection* connection,
               InterfaceRequest<ViewManagerClient> request) override {
-    last_view_manager_client_ = new TestViewManagerClientConnection();
-    BindToRequest(last_view_manager_client_, &request);
-  }
-  void Create(ApplicationConnection* connection,
-              InterfaceRequest<WindowManagerInternalService> request) override {
-    BindToRequest(
-        new WindowManagerInternalServiceImpl(last_view_manager_client_),
-        &request);
+    BindToRequest(new TestViewManagerClientConnection(), &request);
   }
 
  private:
-  // Used so that TestViewManagerClientConnection and
-  // WindowManagerInternalServiceImpl can share the same TestChangeTracker.
-  TestViewManagerClientConnection* last_view_manager_client_;
   ScopedVector<ApplicationImpl> apps_;
 
   DISALLOW_COPY_AND_ASSIGN(EmbedApplicationLoader);
 };
 
-class TestWindowManagerImpl
-    : public InterfaceImpl<WindowManager>,
-      public InterfaceFactory<WindowManagerInternalService> {
+class TestWindowManagerImpl : public InterfaceImpl<WindowManager> {
  public:
   explicit TestWindowManagerImpl(ApplicationConnection* connection)
       : view_manager_client_(nullptr), got_initial_embed_(false) {
     // WindowManager is expected to establish initial connection to VM.
     ApplicationConnection* view_manager_app =
         connection->ConnectToApplication("mojo:view_manager");
-    view_manager_app->AddService<WindowManagerInternalService>(this);
     view_manager_app->ConnectToService(&view_manager_);
+    view_manager_app->ConnectToService(&window_manager_client_);
 
     view_manager_client_ = new TestViewManagerClientConnection();
     view_manager_.set_client(view_manager_client_);
+    view_manager_client_->proxy()->set_window_manager_client(
+        window_manager_client_.get());
     view_manager_client_->proxy()->set_view_manager(view_manager_.get());
   }
 
@@ -519,17 +485,10 @@
     view_manager_client_->tracker()->DelegateEmbed(url);
   }
 
-  // InterfaceFactory<>:
-  virtual void Create(
-      ApplicationConnection* connection,
-      InterfaceRequest<WindowManagerInternalService> request) override {
-    BindToRequest(new WindowManagerInternalServiceImpl(view_manager_client_),
-                  &request);
-  }
-
  private:
   ViewManagerServicePtr view_manager_;
   TestViewManagerClientConnection* view_manager_client_;
+  WindowManagerInternalClientPtr window_manager_client_;
 
   // Did we get Embed() yet?
   bool got_initial_embed_;
diff --git a/mojo/services/window_manager/BUILD.gn b/mojo/services/window_manager/BUILD.gn
index a015384..6721ae9 100644
--- a/mojo/services/window_manager/BUILD.gn
+++ b/mojo/services/window_manager/BUILD.gn
@@ -25,11 +25,11 @@
 # GYP version: mojo/mojo_services.gypi:mojo_core_window_manager_lib
 source_set("lib") {
   sources = [
+    "native_viewport_event_dispatcher_impl.cc",
+    "native_viewport_event_dispatcher_impl.h",
     "window_manager_app.cc",
     "window_manager_app.h",
     "window_manager_delegate.h",
-    "window_manager_internal_service_impl.cc",
-    "window_manager_internal_service_impl.h",
     "window_manager_impl.cc",
     "window_manager_impl.h",
     "window_manager_service2_impl.cc",
@@ -52,6 +52,7 @@
     "//mojo/converters/input_events",
     "//mojo/services/public/cpp/view_manager",
     "//mojo/public/interfaces/application:application",
+    "//mojo/services/public/interfaces/native_viewport",
     "//mojo/services/public/interfaces/window_manager",
     "//mojo/services/public/interfaces/window_manager2",
   ]
diff --git a/mojo/services/window_manager/native_viewport_event_dispatcher_impl.cc b/mojo/services/window_manager/native_viewport_event_dispatcher_impl.cc
new file mode 100644
index 0000000..30764b4
--- /dev/null
+++ b/mojo/services/window_manager/native_viewport_event_dispatcher_impl.cc
@@ -0,0 +1,29 @@
+// Copyright 2014 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 "mojo/services/window_manager/native_viewport_event_dispatcher_impl.h"
+
+#include "mojo/aura/window_tree_host_mojo.h"
+#include "mojo/converters/input_events/input_events_type_converters.h"
+#include "mojo/services/window_manager/window_manager_app.h"
+
+namespace mojo {
+
+NativeViewportEventDispatcherImpl::NativeViewportEventDispatcherImpl(
+    WindowManagerApp* app)
+    : app_(app) {
+}
+NativeViewportEventDispatcherImpl::~NativeViewportEventDispatcherImpl() {
+}
+
+void NativeViewportEventDispatcherImpl::OnEvent(
+    mojo::EventPtr event,
+    const mojo::Callback<void()>& callback) {
+  scoped_ptr<ui::Event> ui_event = event.To<scoped_ptr<ui::Event>>();
+  if (ui_event)
+    app_->host()->SendEventToProcessor(ui_event.get());
+  callback.Run();
+}
+
+}  // namespace mojo
diff --git a/mojo/services/window_manager/native_viewport_event_dispatcher_impl.h b/mojo/services/window_manager/native_viewport_event_dispatcher_impl.h
new file mode 100644
index 0000000..2ef0f74
--- /dev/null
+++ b/mojo/services/window_manager/native_viewport_event_dispatcher_impl.h
@@ -0,0 +1,33 @@
+// Copyright 2014 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 MOJO_SERVICES_WINDOW_MANAGER_NATIVE_VIEWPORT_EVENT_DISPATCHER_IMPL_H_
+#define MOJO_SERVICES_WINDOW_MANAGER_NATIVE_VIEWPORT_EVENT_DISPATCHER_IMPL_H_
+
+#include "base/basictypes.h"
+#include "mojo/services/public/interfaces/native_viewport/native_viewport.mojom.h"
+
+namespace mojo {
+
+class WindowManagerApp;
+
+class NativeViewportEventDispatcherImpl
+    : public InterfaceImpl<NativeViewportEventDispatcher> {
+ public:
+  explicit NativeViewportEventDispatcherImpl(WindowManagerApp* app);
+  ~NativeViewportEventDispatcherImpl() override;
+
+ private:
+  // NativeViewportEventDispatcher:
+  void OnEvent(mojo::EventPtr event,
+               const mojo::Callback<void()>& callback) override;
+
+  WindowManagerApp* app_;
+
+  DISALLOW_COPY_AND_ASSIGN(NativeViewportEventDispatcherImpl);
+};
+
+}  // namespace mojo
+
+#endif  // MOJO_SERVICES_WINDOW_MANAGER_NATIVE_VIEWPORT_EVENT_DISPATCHER_IMPL_H_
diff --git a/mojo/services/window_manager/window_manager_app.cc b/mojo/services/window_manager/window_manager_app.cc
index e9e7747..9af766e 100644
--- a/mojo/services/window_manager/window_manager_app.cc
+++ b/mojo/services/window_manager/window_manager_app.cc
@@ -94,13 +94,12 @@
     : shell_(nullptr),
       window_manager_service2_factory_(this),
       window_manager_factory_(this),
-      window_manager_internal_service_factory_(this),
+      native_viewport_event_dispatcher_factory_(this),
       wrapped_view_manager_delegate_(view_manager_delegate),
       window_manager_delegate_(window_manager_delegate),
       view_manager_(NULL),
       root_(NULL),
-      dummy_delegate_(new DummyDelegate),
-      window_manager_client_(nullptr) {
+      dummy_delegate_(new DummyDelegate) {
 }
 
 WindowManagerApp::~WindowManagerApp() {}
@@ -381,7 +380,9 @@
   view_manager_client_ = ViewManagerClientFactory::WeakBindViewManagerToPipe(
                              pipe.handle0.Pass(), shell_, this).Pass();
 
-  view_manager_app->AddService(&window_manager_internal_service_factory_);
+  view_manager_app->AddService(&native_viewport_event_dispatcher_factory_);
+
+  view_manager_app->ConnectToService(&window_manager_client_);
 }
 
 }  // namespace mojo
diff --git a/mojo/services/window_manager/window_manager_app.h b/mojo/services/window_manager/window_manager_app.h
index e2033a5..20a90ed 100644
--- a/mojo/services/window_manager/window_manager_app.h
+++ b/mojo/services/window_manager/window_manager_app.h
@@ -17,8 +17,9 @@
 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
 #include "mojo/services/public/cpp/view_manager/view_observer.h"
+#include "mojo/services/public/interfaces/window_manager/window_manager_internal.mojom.h"
+#include "mojo/services/window_manager/native_viewport_event_dispatcher_impl.h"
 #include "mojo/services/window_manager/window_manager_impl.h"
-#include "mojo/services/window_manager/window_manager_internal_service_impl.h"
 #include "mojo/services/window_manager/window_manager_service2_impl.h"
 #include "ui/aura/client/focus_change_observer.h"
 #include "ui/events/event_handler.h"
@@ -88,10 +89,6 @@
 
   void InitFocus(wm::FocusRules* rules);
 
-  void set_window_manager_client(WindowManagerInternalClient* client) {
-    window_manager_client_ = client;
-  }
-
   // WindowManagerImpl::Embed() forwards to this. If connected to ViewManager
   // then forwards to delegate, otherwise waits for connection to establish then
   // forwards.
@@ -155,9 +152,9 @@
   InterfaceFactoryImplWithContext<WindowManagerImpl, WindowManagerApp>
       window_manager_factory_;
 
-  InterfaceFactoryImplWithContext<WindowManagerInternalServiceImpl,
+  InterfaceFactoryImplWithContext<NativeViewportEventDispatcherImpl,
                                   WindowManagerApp>
-      window_manager_internal_service_factory_;
+      native_viewport_event_dispatcher_factory_;
 
   ViewManagerDelegate* wrapped_view_manager_delegate_;
   WindowManagerDelegate* window_manager_delegate_;
@@ -178,7 +175,7 @@
 
   scoped_ptr<DummyDelegate> dummy_delegate_;
 
-  WindowManagerInternalClient* window_manager_client_;
+  WindowManagerInternalClientPtr window_manager_client_;
 
   ScopedVector<PendingEmbed> pending_embeds_;
 
diff --git a/mojo/services/window_manager/window_manager_internal_service_impl.cc b/mojo/services/window_manager/window_manager_internal_service_impl.cc
deleted file mode 100644
index 2e321b8..0000000
--- a/mojo/services/window_manager/window_manager_internal_service_impl.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2014 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 "mojo/services/window_manager/window_manager_internal_service_impl.h"
-
-#include "mojo/aura/window_tree_host_mojo.h"
-#include "mojo/converters/input_events/input_events_type_converters.h"
-#include "mojo/services/window_manager/window_manager_app.h"
-#include "mojo/services/window_manager/window_manager_delegate.h"
-
-namespace mojo {
-
-WindowManagerInternalServiceImpl::WindowManagerInternalServiceImpl(
-    WindowManagerApp* app)
-    : app_(app) {
-}
-
-WindowManagerInternalServiceImpl::~WindowManagerInternalServiceImpl() {
-}
-
-void WindowManagerInternalServiceImpl::OnViewInputEvent(mojo::EventPtr event) {
-  scoped_ptr<ui::Event> ui_event = event.To<scoped_ptr<ui::Event>>();
-  if (ui_event)
-    app_->host()->SendEventToProcessor(ui_event.get());
-}
-
-void WindowManagerInternalServiceImpl::OnConnectionEstablished() {
-  app_->set_window_manager_client(client());
-}
-
-}  // namespace mojo
diff --git a/mojo/services/window_manager/window_manager_internal_service_impl.h b/mojo/services/window_manager/window_manager_internal_service_impl.h
deleted file mode 100644
index 3e416f3..0000000
--- a/mojo/services/window_manager/window_manager_internal_service_impl.h
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2014 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 MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_INTERNAL_SERVICE_IMPL_H_
-#define MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_INTERNAL_SERVICE_IMPL_H_
-
-#include "base/basictypes.h"
-#include "mojo/services/public/interfaces/window_manager/window_manager_internal.mojom.h"
-
-namespace mojo {
-
-class WindowManagerApp;
-
-class WindowManagerInternalServiceImpl
-    : public InterfaceImpl<WindowManagerInternalService> {
- public:
-  explicit WindowManagerInternalServiceImpl(WindowManagerApp* app);
-  virtual ~WindowManagerInternalServiceImpl();
-
- private:
-  // WindowManagerInternalServiceImpl:
-  virtual void OnViewInputEvent(mojo::EventPtr event) override;
-
-  // InterfaceImpl:
-  virtual void OnConnectionEstablished() override;
-
-  WindowManagerApp* app_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowManagerInternalServiceImpl);
-};
-
-}  // namespace mojo
-
-#endif  // MOJO_SERVICES_WINDOW_MANAGER_WINDOW_MANAGER_INTERNAL_SERVICE_IMPL_H_