Adds capture to the mojo window_manager.

This adds a CaptureController which manages capture, puts a checkbox
that makes a window have capture in the wm_flow demo, and ports the
relevant unit tests for FocusController.

BUG=442545
R=sky@chromium.org

Review URL: https://codereview.chromium.org/805123003
diff --git a/services/window_manager/window_manager_app.cc b/services/window_manager/window_manager_app.cc
index 023af5f..2c25e2b 100644
--- a/services/window_manager/window_manager_app.cc
+++ b/services/window_manager/window_manager_app.cc
@@ -13,6 +13,7 @@
 #include "mojo/public/interfaces/application/shell.mojom.h"
 #include "mojo/services/view_manager/public/cpp/view.h"
 #include "mojo/services/view_manager/public/cpp/view_manager.h"
+#include "services/window_manager/capture_controller.h"
 #include "services/window_manager/focus_controller.h"
 #include "services/window_manager/focus_rules.h"
 #include "services/window_manager/view_event_dispatcher.h"
@@ -72,13 +73,10 @@
   connections_.erase(connection);
 }
 
-void WindowManagerApp::SetCapture(Id view) {
-  // TODO(erg): Capture. Another pile of worms that is mixed in here.
-
-  // capture_client_->capture_client()->SetCapture(GetWindowForViewId(view));
-
-  // TODO(beng): notify connected clients that capture has changed, probably
-  //             by implementing some capture-client observer.
+void WindowManagerApp::SetCapture(Id view_id) {
+  View* view = view_manager_->GetViewById(view_id);
+  DCHECK(view);
+  capture_controller_->SetCapture(view);
 }
 
 void WindowManagerApp::FocusWindow(Id view_id) {
@@ -98,11 +96,15 @@
 }
 
 void WindowManagerApp::InitFocus(scoped_ptr<FocusRules> rules) {
+  DCHECK(root_);
+
   focus_controller_.reset(new FocusController(rules.Pass()));
   focus_controller_->AddObserver(this);
-
-  DCHECK(root_);
   SetFocusController(root_, focus_controller_.get());
+
+  capture_controller_.reset(new CaptureController);
+  capture_controller_->AddObserver(this);
+  SetCaptureController(root_, capture_controller_.get());
 }
 
 void WindowManagerApp::Embed(
@@ -147,11 +149,6 @@
 
   RegisterSubtree(root_);
 
-  // TODO(erg): Also move the capture client over.
-  //
-  // capture_client_.reset(
-  //     new wm::ScopedCaptureClient(window_tree_host_->window()));
-
   if (wrapped_view_manager_delegate_) {
     wrapped_view_manager_delegate_->OnEmbed(
         view_manager, root, exported_services, imported_services.Pass());
@@ -203,6 +200,8 @@
   root_ = nullptr;
   if (focus_controller_)
     focus_controller_->RemoveObserver(this);
+  if (capture_controller_)
+    capture_controller_->RemoveObserver(this);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -247,6 +246,20 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+// WindowManagerApp, mojo::CaptureControllerObserver implementation:
+
+void WindowManagerApp::OnCaptureChanged(View* gained_capture,
+                                        View* lost_capture) {
+  for (Connections::const_iterator it = connections_.begin();
+       it != connections_.end(); ++it) {
+    (*it)->NotifyCaptureChanged(GetIdForView(gained_capture),
+                                GetIdForView(lost_capture));
+  }
+  if (gained_capture)
+    gained_capture->MoveToFront();
+}
+
+////////////////////////////////////////////////////////////////////////////////
 // WindowManagerApp, private:
 
 void WindowManagerApp::RegisterSubtree(View* view) {