exo: Run exo in mus+ash

Add WMHelperAsh and WMHelperMus. They are for accessing WM
related features in ash and mus+ash, and exo will create one
of those two helpers based on the WM environment.

Know issue: All methods of WMHelperMus are not implemented,
so the exo doesn't response to any events.

BUG=637914
TEST=manually with https://github.com/phuang/waylandcxx

Review-Url: https://codereview.chromium.org/2250863003
Cr-Commit-Position: refs/heads/master@{#412861}
diff --git a/chrome/browser/chrome_browser_main_extra_parts_exo.cc b/chrome/browser/chrome_browser_main_extra_parts_exo.cc
index ee29d96..8221f549 100644
--- a/chrome/browser/chrome_browser_main_extra_parts_exo.cc
+++ b/chrome/browser/chrome_browser_main_extra_parts_exo.cc
@@ -17,6 +17,8 @@
 #include "chrome/common/chrome_switches.h"
 #include "components/exo/display.h"
 #include "components/exo/wayland/server.h"
+#include "components/exo/wm_helper_ash.h"
+#include "components/exo/wm_helper_mus.h"
 #include "content/public/browser/browser_thread.h"
 #include "ui/arc/notification/arc_notification_surface_manager.h"
 
@@ -110,25 +112,33 @@
 };
 #endif
 
-ChromeBrowserMainExtraPartsExo::ChromeBrowserMainExtraPartsExo()
-    : arc_notification_surface_manager_(new arc::ArcNotificationSurfaceManager),
-      display_(new exo::Display(arc_notification_surface_manager_.get())) {}
+ChromeBrowserMainExtraPartsExo::ChromeBrowserMainExtraPartsExo() {}
 
 ChromeBrowserMainExtraPartsExo::~ChromeBrowserMainExtraPartsExo() {}
 
 void ChromeBrowserMainExtraPartsExo::PreProfileInit() {
-  if (!chrome::ShouldOpenAshOnStartup())
+  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableWaylandServer))
     return;
 
-  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kEnableWaylandServer)) {
-    wayland_server_ = exo::wayland::Server::Create(display_.get());
-    wayland_watcher_ =
-        base::WrapUnique(new WaylandWatcher(wayland_server_.get()));
-  }
+  arc_notification_surface_manager_ =
+      base::MakeUnique<arc::ArcNotificationSurfaceManager>();
+  if (chrome::IsRunningInMash())
+    wm_helper_ = base::MakeUnique<exo::WMHelperMus>();
+  else
+    wm_helper_ = base::MakeUnique<exo::WMHelperAsh>();
+  exo::WMHelper::SetInstance(wm_helper_.get());
+  display_ =
+      base::MakeUnique<exo::Display>(arc_notification_surface_manager_.get());
+  wayland_server_ = exo::wayland::Server::Create(display_.get());
+  wayland_watcher_ = base::MakeUnique<WaylandWatcher>(wayland_server_.get());
 }
 
 void ChromeBrowserMainExtraPartsExo::PostMainMessageLoopRun() {
   wayland_watcher_.reset();
   wayland_server_.reset();
+  if (wm_helper_) {
+    exo::WMHelper::SetInstance(nullptr);
+    wm_helper_.reset();
+  }
 }
diff --git a/chrome/browser/chrome_browser_main_extra_parts_exo.h b/chrome/browser/chrome_browser_main_extra_parts_exo.h
index 8fc5f060..7e97f85 100644
--- a/chrome/browser/chrome_browser_main_extra_parts_exo.h
+++ b/chrome/browser/chrome_browser_main_extra_parts_exo.h
@@ -12,6 +12,7 @@
 
 namespace exo {
 class Display;
+class WMHelper;
 namespace wayland {
 class Server;
 }
@@ -33,6 +34,7 @@
  private:
   std::unique_ptr<arc::ArcNotificationSurfaceManager>
       arc_notification_surface_manager_;
+  std::unique_ptr<exo::WMHelper> wm_helper_;
   std::unique_ptr<exo::Display> display_;
   std::unique_ptr<exo::wayland::Server> wayland_server_;
   class WaylandWatcher;
diff --git a/components/exo/BUILD.gn b/components/exo/BUILD.gn
index 16af5ce..48f04c3 100644
--- a/components/exo/BUILD.gn
+++ b/components/exo/BUILD.gn
@@ -38,6 +38,10 @@
     "touch_delegate.h",
     "wm_helper.cc",
     "wm_helper.h",
+    "wm_helper_ash.cc",
+    "wm_helper_ash.h",
+    "wm_helper_mus.cc",
+    "wm_helper_mus.h",
   ]
 
   deps = [
@@ -70,6 +74,7 @@
   ]
 
   deps = [
+    ":exo",
     "//ash:test_support",
     "//base",
     "//gpu",
diff --git a/components/exo/test/exo_test_base.cc b/components/exo/test/exo_test_base.cc
index 738320d7..c6e4d47 100644
--- a/components/exo/test/exo_test_base.cc
+++ b/components/exo/test/exo_test_base.cc
@@ -5,7 +5,9 @@
 #include "components/exo/test/exo_test_base.h"
 
 #include "base/command_line.h"
+#include "base/memory/ptr_util.h"
 #include "components/exo/test/exo_test_helper.h"
+#include "components/exo/wm_helper_ash.h"
 #include "ui/wm/core/wm_core_switches.h"
 
 namespace exo {
@@ -23,9 +25,13 @@
   // Disable window animation when running tests.
   command_line->AppendSwitch(wm::switches::kWindowAnimationsDisabled);
   AshTestBase::SetUp();
+  wm_helper_ = base::MakeUnique<WMHelperAsh>();
+  WMHelper::SetInstance(wm_helper_.get());
 }
 
 void ExoTestBase::TearDown() {
+  WMHelper::SetInstance(nullptr);
+  wm_helper_.reset();
   AshTestBase::TearDown();
 }
 
diff --git a/components/exo/test/exo_test_base.h b/components/exo/test/exo_test_base.h
index 0042595..df5de17 100644
--- a/components/exo/test/exo_test_base.h
+++ b/components/exo/test/exo_test_base.h
@@ -11,6 +11,8 @@
 #include "base/macros.h"
 
 namespace exo {
+class WMHelper;
+
 namespace test {
 class ExoTestHelper;
 
@@ -27,6 +29,7 @@
 
  private:
   std::unique_ptr<ExoTestHelper> exo_test_helper_;
+  std::unique_ptr<WMHelper> wm_helper_;
 
   DISALLOW_COPY_AND_ASSIGN(ExoTestBase);
 };
diff --git a/components/exo/wm_helper.cc b/components/exo/wm_helper.cc
index f73138a4..6e4b495 100644
--- a/components/exo/wm_helper.cc
+++ b/components/exo/wm_helper.cc
@@ -4,56 +4,30 @@
 
 #include "components/exo/wm_helper.h"
 
-#include "ash/common/wm/maximize_mode/maximize_mode_controller.h"
-#include "ash/common/wm_shell.h"
-#include "ash/display/display_manager.h"
-#include "ash/shell.h"
-#include "base/memory/singleton.h"
-#include "ui/aura/client/focus_client.h"
-#include "ui/wm/public/activation_client.h"
+#include "base/memory/ptr_util.h"
 
 namespace exo {
+namespace {
+WMHelper* g_instance = nullptr;
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // WMHelper, public:
 
-WMHelper::WMHelper() {
-  ash::WmShell::Get()->AddShellObserver(this);
-  ash::Shell::GetInstance()->activation_client()->AddObserver(this);
-  aura::client::FocusClient* focus_client =
-      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
-  focus_client->AddObserver(this);
-}
+WMHelper::WMHelper() {}
 
-WMHelper::~WMHelper() {
-  if (!ash::Shell::HasInstance())
-    return;
-  aura::client::FocusClient* focus_client =
-      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
-  focus_client->AddObserver(this);
-  focus_client->RemoveObserver(this);
-  ash::Shell::GetInstance()->activation_client()->RemoveObserver(this);
-  ash::WmShell::Get()->RemoveShellObserver(this);
+WMHelper::~WMHelper() {}
+
+// static
+void WMHelper::SetInstance(WMHelper* helper) {
+  DCHECK_NE(!!helper, !!g_instance);
+  g_instance = helper;
 }
 
 // static
 WMHelper* WMHelper::GetInstance() {
-  return base::Singleton<WMHelper>::get();
-}
-
-const ash::DisplayInfo& WMHelper::GetDisplayInfo(int64_t display_id) const {
-  return ash::Shell::GetInstance()->display_manager()->GetDisplayInfo(
-      display_id);
-}
-
-// static
-aura::Window* WMHelper::GetContainer(int container_id) {
-  return ash::Shell::GetContainer(ash::Shell::GetTargetRootWindow(),
-                                  container_id);
-}
-
-aura::Window* WMHelper::GetActiveWindow() const {
-  return ash::Shell::GetInstance()->activation_client()->GetActiveWindow();
+  DCHECK(g_instance);
+  return g_instance;
 }
 
 void WMHelper::AddActivationObserver(ActivationObserver* observer) {
@@ -64,12 +38,6 @@
   activation_observers_.RemoveObserver(observer);
 }
 
-aura::Window* WMHelper::GetFocusedWindow() const {
-  aura::client::FocusClient* focus_client =
-      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
-  return focus_client->GetFocusedWindow();
-}
-
 void WMHelper::AddFocusObserver(FocusObserver* observer) {
   focus_observers_.AddObserver(observer);
 }
@@ -78,10 +46,6 @@
   focus_observers_.RemoveObserver(observer);
 }
 
-ui::CursorSetType WMHelper::GetCursorSet() const {
-  return ash::Shell::GetInstance()->cursor_manager()->GetCursorSet();
-}
-
 void WMHelper::AddCursorObserver(CursorObserver* observer) {
   cursor_observers_.AddObserver(observer);
 }
@@ -90,32 +54,6 @@
   cursor_observers_.RemoveObserver(observer);
 }
 
-void WMHelper::AddPreTargetHandler(ui::EventHandler* handler) {
-  ash::Shell::GetInstance()->AddPreTargetHandler(handler);
-}
-
-void WMHelper::PrependPreTargetHandler(ui::EventHandler* handler) {
-  ash::Shell::GetInstance()->PrependPreTargetHandler(handler);
-}
-
-void WMHelper::RemovePreTargetHandler(ui::EventHandler* handler) {
-  ash::Shell::GetInstance()->RemovePreTargetHandler(handler);
-}
-
-void WMHelper::AddPostTargetHandler(ui::EventHandler* handler) {
-  ash::Shell::GetInstance()->AddPostTargetHandler(handler);
-}
-
-void WMHelper::RemovePostTargetHandler(ui::EventHandler* handler) {
-  ash::Shell::GetInstance()->RemovePostTargetHandler(handler);
-}
-
-bool WMHelper::IsMaximizeModeWindowManagerEnabled() const {
-  return ash::WmShell::Get()
-      ->maximize_mode_controller()
-      ->IsMaximizeModeWindowManagerEnabled();
-}
-
 void WMHelper::AddMaximizeModeObserver(MaximizeModeObserver* observer) {
   maximize_mode_observers_.AddObserver(observer);
 }
@@ -124,36 +62,34 @@
   maximize_mode_observers_.RemoveObserver(observer);
 }
 
-void WMHelper::OnWindowActivated(
-    aura::client::ActivationChangeObserver::ActivationReason reason,
-    aura::Window* gained_active,
-    aura::Window* lost_active) {
+void WMHelper::NotifyWindowActivated(aura::Window* gained_active,
+                                     aura::Window* lost_active) {
   FOR_EACH_OBSERVER(ActivationObserver, activation_observers_,
                     OnWindowActivated(gained_active, lost_active));
 }
 
-void WMHelper::OnWindowFocused(aura::Window* gained_focus,
-                               aura::Window* lost_focus) {
+void WMHelper::NotifyWindowFocused(aura::Window* gained_focus,
+                                   aura::Window* lost_focus) {
   FOR_EACH_OBSERVER(FocusObserver, focus_observers_,
                     OnWindowFocused(gained_focus, lost_focus));
 }
 
-void WMHelper::OnCursorVisibilityChanged(bool is_visible) {
+void WMHelper::NotifyCursorVisibilityChanged(bool is_visible) {
   FOR_EACH_OBSERVER(CursorObserver, cursor_observers_,
                     OnCursorVisibilityChanged(is_visible));
 }
 
-void WMHelper::OnCursorSetChanged(ui::CursorSetType cursor_set) {
+void WMHelper::NotifyCursorSetChanged(ui::CursorSetType cursor_set) {
   FOR_EACH_OBSERVER(CursorObserver, cursor_observers_,
                     OnCursorSetChanged(cursor_set));
 }
 
-void WMHelper::OnMaximizeModeStarted() {
+void WMHelper::NotifyMaximizeModeStarted() {
   FOR_EACH_OBSERVER(MaximizeModeObserver, maximize_mode_observers_,
                     OnMaximizeModeStarted());
 }
 
-void WMHelper::OnMaximizeModeEnded() {
+void WMHelper::NotifyMaximizeModeEnded() {
   FOR_EACH_OBSERVER(MaximizeModeObserver, maximize_mode_observers_,
                     OnMaximizeModeEnded());
 }
diff --git a/components/exo/wm_helper.h b/components/exo/wm_helper.h
index d43aef88..676c97f 100644
--- a/components/exo/wm_helper.h
+++ b/components/exo/wm_helper.h
@@ -5,12 +5,9 @@
 #ifndef COMPONENTS_EXO_WM_HELPER_H_
 #define COMPONENTS_EXO_WM_HELPER_H_
 
-#include "ash/common/shell_observer.h"
 #include "base/macros.h"
 #include "base/observer_list.h"
-#include "ui/aura/client/cursor_client_observer.h"
-#include "ui/aura/client/focus_change_observer.h"
-#include "ui/wm/public/activation_change_observer.h"
+#include "ui/base/cursor/cursor.h"
 
 namespace ash {
 class DisplayInfo;
@@ -24,18 +21,10 @@
 class EventHandler;
 }
 
-namespace base {
-template <typename T>
-struct DefaultSingletonTraits;
-}
-
 namespace exo {
 
 // A helper class for accessing WindowManager related features.
-class WMHelper : public aura::client::ActivationChangeObserver,
-                 public aura::client::FocusChangeObserver,
-                 public aura::client::CursorClientObserver,
-                 public ash::ShellObserver {
+class WMHelper {
  public:
   class ActivationObserver {
    public:
@@ -73,58 +62,45 @@
     virtual ~MaximizeModeObserver() {}
   };
 
+  virtual ~WMHelper();
+
+  static void SetInstance(WMHelper* helper);
   static WMHelper* GetInstance();
 
-  const ash::DisplayInfo& GetDisplayInfo(int64_t display_id) const;
-  aura::Window* GetContainer(int container_id);
-
-  aura::Window* GetActiveWindow() const;
   void AddActivationObserver(ActivationObserver* observer);
   void RemoveActivationObserver(ActivationObserver* observer);
-
-  aura::Window* GetFocusedWindow() const;
   void AddFocusObserver(FocusObserver* observer);
   void RemoveFocusObserver(FocusObserver* observer);
-
-  ui::CursorSetType GetCursorSet() const;
   void AddCursorObserver(CursorObserver* observer);
   void RemoveCursorObserver(CursorObserver* observer);
-
-  void AddPreTargetHandler(ui::EventHandler* handler);
-  void PrependPreTargetHandler(ui::EventHandler* handler);
-  void RemovePreTargetHandler(ui::EventHandler* handler);
-
-  void AddPostTargetHandler(ui::EventHandler* handler);
-  void RemovePostTargetHandler(ui::EventHandler* handler);
-
-  bool IsMaximizeModeWindowManagerEnabled() const;
   void AddMaximizeModeObserver(MaximizeModeObserver* observer);
   void RemoveMaximizeModeObserver(MaximizeModeObserver* observer);
 
- private:
+  virtual const ash::DisplayInfo GetDisplayInfo(int64_t display_id) const = 0;
+  virtual aura::Window* GetContainer(int container_id) = 0;
+  virtual aura::Window* GetActiveWindow() const = 0;
+  virtual aura::Window* GetFocusedWindow() const = 0;
+  virtual ui::CursorSetType GetCursorSet() const = 0;
+  virtual void AddPreTargetHandler(ui::EventHandler* handler) = 0;
+  virtual void PrependPreTargetHandler(ui::EventHandler* handler) = 0;
+  virtual void RemovePreTargetHandler(ui::EventHandler* handler) = 0;
+  virtual void AddPostTargetHandler(ui::EventHandler* handler) = 0;
+  virtual void RemovePostTargetHandler(ui::EventHandler* handler) = 0;
+  virtual bool IsMaximizeModeWindowManagerEnabled() const = 0;
+
+ protected:
   WMHelper();
-  ~WMHelper() override;
 
-  friend struct base::DefaultSingletonTraits<WMHelper>;
+  void NotifyWindowActivated(aura::Window* gained_active,
+                             aura::Window* lost_active);
+  void NotifyWindowFocused(aura::Window* gained_focus,
+                           aura::Window* lost_focus);
+  void NotifyCursorVisibilityChanged(bool is_visible);
+  void NotifyCursorSetChanged(ui::CursorSetType cursor_set);
+  void NotifyMaximizeModeStarted();
+  void NotifyMaximizeModeEnded();
 
-  // Overriden from aura::client::ActivationChangeObserver:
-  void OnWindowActivated(
-      aura::client::ActivationChangeObserver::ActivationReason reason,
-      aura::Window* gained_active,
-      aura::Window* lost_active) override;
-
-  // Overriden from aura::client::FocusChangeObserver:
-  void OnWindowFocused(aura::Window* gained_focus,
-                       aura::Window* lost_focus) override;
-
-  // Overriden from aura::client::CursorClientObserver:
-  void OnCursorVisibilityChanged(bool is_visible) override;
-  void OnCursorSetChanged(ui::CursorSetType cursor_set) override;
-
-  // Overriden from ash::ShellObserver:
-  void OnMaximizeModeStarted() override;
-  void OnMaximizeModeEnded() override;
-
+ private:
   base::ObserverList<ActivationObserver> activation_observers_;
   base::ObserverList<FocusObserver> focus_observers_;
   base::ObserverList<CursorObserver> cursor_observers_;
diff --git a/components/exo/wm_helper_ash.cc b/components/exo/wm_helper_ash.cc
new file mode 100644
index 0000000..fb3bde6
--- /dev/null
+++ b/components/exo/wm_helper_ash.cc
@@ -0,0 +1,119 @@
+// 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.
+
+#include "components/exo/wm_helper_ash.h"
+
+#include "ash/common/wm/maximize_mode/maximize_mode_controller.h"
+#include "ash/common/wm_shell.h"
+#include "ash/display/display_manager.h"
+#include "ash/shell.h"
+#include "base/memory/singleton.h"
+#include "ui/aura/client/focus_client.h"
+#include "ui/wm/public/activation_client.h"
+
+namespace exo {
+
+////////////////////////////////////////////////////////////////////////////////
+// WMHelperAsh, public:
+
+WMHelperAsh::WMHelperAsh() {
+  ash::WmShell::Get()->AddShellObserver(this);
+  ash::Shell::GetInstance()->activation_client()->AddObserver(this);
+  aura::client::FocusClient* focus_client =
+      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
+  focus_client->AddObserver(this);
+}
+
+WMHelperAsh::~WMHelperAsh() {
+  if (!ash::Shell::HasInstance())
+    return;
+  aura::client::FocusClient* focus_client =
+      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
+  focus_client->RemoveObserver(this);
+  ash::Shell::GetInstance()->activation_client()->RemoveObserver(this);
+  ash::WmShell::Get()->RemoveShellObserver(this);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// WMHelperAsh, private:
+
+const ash::DisplayInfo WMHelperAsh::GetDisplayInfo(int64_t display_id) const {
+  return ash::Shell::GetInstance()->display_manager()->GetDisplayInfo(
+      display_id);
+}
+
+aura::Window* WMHelperAsh::GetContainer(int container_id) {
+  return ash::Shell::GetContainer(ash::Shell::GetTargetRootWindow(),
+                                  container_id);
+}
+
+aura::Window* WMHelperAsh::GetActiveWindow() const {
+  return ash::Shell::GetInstance()->activation_client()->GetActiveWindow();
+}
+
+aura::Window* WMHelperAsh::GetFocusedWindow() const {
+  aura::client::FocusClient* focus_client =
+      aura::client::GetFocusClient(ash::Shell::GetPrimaryRootWindow());
+  return focus_client->GetFocusedWindow();
+}
+
+ui::CursorSetType WMHelperAsh::GetCursorSet() const {
+  return ash::Shell::GetInstance()->cursor_manager()->GetCursorSet();
+}
+
+void WMHelperAsh::AddPreTargetHandler(ui::EventHandler* handler) {
+  ash::Shell::GetInstance()->AddPreTargetHandler(handler);
+}
+
+void WMHelperAsh::PrependPreTargetHandler(ui::EventHandler* handler) {
+  ash::Shell::GetInstance()->PrependPreTargetHandler(handler);
+}
+
+void WMHelperAsh::RemovePreTargetHandler(ui::EventHandler* handler) {
+  ash::Shell::GetInstance()->RemovePreTargetHandler(handler);
+}
+
+void WMHelperAsh::AddPostTargetHandler(ui::EventHandler* handler) {
+  ash::Shell::GetInstance()->AddPostTargetHandler(handler);
+}
+
+void WMHelperAsh::RemovePostTargetHandler(ui::EventHandler* handler) {
+  ash::Shell::GetInstance()->RemovePostTargetHandler(handler);
+}
+
+bool WMHelperAsh::IsMaximizeModeWindowManagerEnabled() const {
+  return ash::WmShell::Get()
+      ->maximize_mode_controller()
+      ->IsMaximizeModeWindowManagerEnabled();
+}
+
+void WMHelperAsh::OnWindowActivated(
+    aura::client::ActivationChangeObserver::ActivationReason reason,
+    aura::Window* gained_active,
+    aura::Window* lost_active) {
+  NotifyWindowActivated(gained_active, lost_active);
+}
+
+void WMHelperAsh::OnWindowFocused(aura::Window* gained_focus,
+                                  aura::Window* lost_focus) {
+  NotifyWindowFocused(gained_focus, lost_focus);
+}
+
+void WMHelperAsh::OnCursorVisibilityChanged(bool is_visible) {
+  NotifyCursorVisibilityChanged(is_visible);
+}
+
+void WMHelperAsh::OnCursorSetChanged(ui::CursorSetType cursor_set) {
+  NotifyCursorSetChanged(cursor_set);
+}
+
+void WMHelperAsh::OnMaximizeModeStarted() {
+  NotifyMaximizeModeStarted();
+}
+
+void WMHelperAsh::OnMaximizeModeEnded() {
+  NotifyMaximizeModeEnded();
+}
+
+}  // namespace exo
diff --git a/components/exo/wm_helper_ash.h b/components/exo/wm_helper_ash.h
new file mode 100644
index 0000000..fe12c07
--- /dev/null
+++ b/components/exo/wm_helper_ash.h
@@ -0,0 +1,64 @@
+// 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.
+
+#ifndef COMPONENTS_EXO_WM_HELPER_ASH_H_
+#define COMPONENTS_EXO_WM_HELPER_ASH_H_
+
+#include "ash/common/shell_observer.h"
+#include "base/macros.h"
+#include "components/exo/wm_helper.h"
+#include "ui/aura/client/cursor_client_observer.h"
+#include "ui/aura/client/focus_change_observer.h"
+#include "ui/wm/public/activation_change_observer.h"
+
+namespace exo {
+
+// A helper class for accessing WindowManager related features.
+class WMHelperAsh : public WMHelper,
+                    public aura::client::ActivationChangeObserver,
+                    public aura::client::FocusChangeObserver,
+                    public aura::client::CursorClientObserver,
+                    public ash::ShellObserver {
+ public:
+  WMHelperAsh();
+  ~WMHelperAsh() override;
+
+  // Overriden from WMHelper:
+  const ash::DisplayInfo GetDisplayInfo(int64_t display_id) const override;
+  aura::Window* GetContainer(int container_id) override;
+  aura::Window* GetActiveWindow() const override;
+  aura::Window* GetFocusedWindow() const override;
+  ui::CursorSetType GetCursorSet() const override;
+  void AddPreTargetHandler(ui::EventHandler* handler) override;
+  void PrependPreTargetHandler(ui::EventHandler* handler) override;
+  void RemovePreTargetHandler(ui::EventHandler* handler) override;
+  void AddPostTargetHandler(ui::EventHandler* handler) override;
+  void RemovePostTargetHandler(ui::EventHandler* handler) override;
+  bool IsMaximizeModeWindowManagerEnabled() const override;
+
+  // Overriden from aura::client::ActivationChangeObserver:
+  void OnWindowActivated(
+      aura::client::ActivationChangeObserver::ActivationReason reason,
+      aura::Window* gained_active,
+      aura::Window* lost_active) override;
+
+  // Overriden from aura::client::FocusChangeObserver:
+  void OnWindowFocused(aura::Window* gained_focus,
+                       aura::Window* lost_focus) override;
+
+  // Overriden from aura::client::CursorClientObserver:
+  void OnCursorVisibilityChanged(bool is_visible) override;
+  void OnCursorSetChanged(ui::CursorSetType cursor_set) override;
+
+  // Overriden from ash::ShellObserver:
+  void OnMaximizeModeStarted() override;
+  void OnMaximizeModeEnded() override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WMHelperAsh);
+};
+
+}  // namespace exo
+
+#endif  // COMPONENTS_EXO_WM_HELPER_H_
diff --git a/components/exo/wm_helper_mus.cc b/components/exo/wm_helper_mus.cc
new file mode 100644
index 0000000..315a70c
--- /dev/null
+++ b/components/exo/wm_helper_mus.cc
@@ -0,0 +1,71 @@
+// 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.
+
+#include "components/exo/wm_helper_mus.h"
+
+#include "ash/common/display/display_info.h"
+
+namespace exo {
+
+////////////////////////////////////////////////////////////////////////////////
+// WMHelperMus, public:
+
+WMHelperMus::WMHelperMus() {}
+
+WMHelperMus::~WMHelperMus() {}
+
+////////////////////////////////////////////////////////////////////////////////
+// WMHelperMus, private:
+
+const ash::DisplayInfo WMHelperMus::GetDisplayInfo(int64_t display_id) const {
+  NOTIMPLEMENTED();
+  return ash::DisplayInfo();
+}
+
+aura::Window* WMHelperMus::GetContainer(int container_id) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+aura::Window* WMHelperMus::GetActiveWindow() const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+aura::Window* WMHelperMus::GetFocusedWindow() const {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
+ui::CursorSetType WMHelperMus::GetCursorSet() const {
+  NOTIMPLEMENTED();
+  return ui::CursorSetType::CURSOR_SET_NORMAL;
+}
+
+void WMHelperMus::AddPreTargetHandler(ui::EventHandler* handler) {
+  NOTIMPLEMENTED();
+}
+
+void WMHelperMus::PrependPreTargetHandler(ui::EventHandler* handler) {
+  NOTIMPLEMENTED();
+}
+
+void WMHelperMus::RemovePreTargetHandler(ui::EventHandler* handler) {
+  NOTIMPLEMENTED();
+}
+
+void WMHelperMus::AddPostTargetHandler(ui::EventHandler* handler) {
+  NOTIMPLEMENTED();
+}
+
+void WMHelperMus::RemovePostTargetHandler(ui::EventHandler* handler) {
+  NOTIMPLEMENTED();
+}
+
+bool WMHelperMus::IsMaximizeModeWindowManagerEnabled() const {
+  NOTIMPLEMENTED();
+  return false;
+}
+
+}  // namespace exo
diff --git a/components/exo/wm_helper_mus.h b/components/exo/wm_helper_mus.h
new file mode 100644
index 0000000..ea03df7
--- /dev/null
+++ b/components/exo/wm_helper_mus.h
@@ -0,0 +1,38 @@
+// 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.
+
+#ifndef COMPONENTS_EXO_WM_HELPER_MUS_H_
+#define COMPONENTS_EXO_WM_HELPER_MUS_H_
+
+#include "base/macros.h"
+#include "components/exo/wm_helper.h"
+
+namespace exo {
+
+// A helper class for accessing WindowManager related features.
+class WMHelperMus : public WMHelper {
+ public:
+  WMHelperMus();
+  ~WMHelperMus() override;
+
+  // Overriden from WMHelper:
+  const ash::DisplayInfo GetDisplayInfo(int64_t display_id) const override;
+  aura::Window* GetContainer(int container_id) override;
+  aura::Window* GetActiveWindow() const override;
+  aura::Window* GetFocusedWindow() const override;
+  ui::CursorSetType GetCursorSet() const override;
+  void AddPreTargetHandler(ui::EventHandler* handler) override;
+  void PrependPreTargetHandler(ui::EventHandler* handler) override;
+  void RemovePreTargetHandler(ui::EventHandler* handler) override;
+  void AddPostTargetHandler(ui::EventHandler* handler) override;
+  void RemovePostTargetHandler(ui::EventHandler* handler) override;
+  bool IsMaximizeModeWindowManagerEnabled() const override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WMHelperMus);
+};
+
+}  // namespace exo
+
+#endif  // COMPONENTS_EXO_WM_HELPER_H_