Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / mojo / services / public / cpp / view_manager / lib / view_manager_client_impl.cc
index cb7b071..ec4ec61 100644 (file)
 #include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h"
 
 #include "base/bind.h"
+#include "base/command_line.h"
 #include "base/message_loop/message_loop.h"
-#include "mojo/public/cpp/application/application.h"
+#include "base/stl_util.h"
+#include "mojo/public/cpp/application/application_connection.h"
 #include "mojo/public/cpp/application/connect.h"
-#include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
-#include "mojo/services/public/cpp/view_manager/lib/node_private.h"
+#include "mojo/public/cpp/application/service_provider_impl.h"
+#include "mojo/public/interfaces/application/service_provider.mojom.h"
 #include "mojo/services/public/cpp/view_manager/lib/view_private.h"
-#include "mojo/services/public/cpp/view_manager/node_observer.h"
 #include "mojo/services/public/cpp/view_manager/util.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/cpp/view_manager/window_manager_delegate.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/png_codec.h"
 
 namespace mojo {
-namespace view_manager {
 
 Id MakeTransportId(ConnectionSpecificId connection_id,
                    ConnectionSpecificId local_id) {
   return (connection_id << 16) | local_id;
 }
 
-// Helper called to construct a local node/view object from transport data.
-Node* AddNodeToViewManager(ViewManagerClientImpl* client,
-                           Node* parent,
-                           Id node_id,
+// Helper called to construct a local view object from transport data.
+View* AddViewToViewManager(ViewManagerClientImpl* client,
+                           View* parent,
                            Id view_id,
                            const gfx::Rect& bounds) {
   // We don't use the ctor that takes a ViewManager here, since it will call
-  // back to the service and attempt to create a new node.
-  Node* node = NodePrivate::LocalCreate();
-  NodePrivate private_node(node);
-  private_node.set_view_manager(client);
-  private_node.set_id(node_id);
-  private_node.LocalSetBounds(gfx::Rect(), bounds);
+  // back to the service and attempt to create a new view.
+  View* view = ViewPrivate::LocalCreate();
+  ViewPrivate private_view(view);
+  private_view.set_view_manager(client);
+  private_view.set_id(view_id);
+  client->AddView(view);
+  private_view.LocalSetBounds(gfx::Rect(), bounds);
   if (parent)
-    NodePrivate(parent).LocalAddChild(node);
-  client->AddNode(node);
-
-  // View.
-  if (view_id != 0) {
-    View* view = ViewPrivate::LocalCreate();
-    ViewPrivate private_view(view);
-    private_view.set_view_manager(client);
-    private_view.set_id(view_id);
-    private_view.set_node(node);
-    // TODO(beng): this broadcasts notifications locally... do we want this? I
-    //             don't think so. same story for LocalAddChild above!
-    private_node.LocalSetActiveView(view);
-    client->AddView(view);
-  }
-  return node;
-}
-
-Node* BuildNodeTree(ViewManagerClientImpl* client,
-                    const Array<NodeDataPtr>& nodes) {
-  std::vector<Node*> parents;
-  Node* root = NULL;
-  Node* last_node = NULL;
-  for (size_t i = 0; i < nodes.size(); ++i) {
-    if (last_node && nodes[i]->parent_id == last_node->id()) {
-      parents.push_back(last_node);
+    ViewPrivate(parent).LocalAddChild(view);
+  return view;
+}
+
+View* BuildViewTree(ViewManagerClientImpl* client,
+                    const Array<ViewDataPtr>& views,
+                    View* initial_parent) {
+  std::vector<View*> parents;
+  View* root = NULL;
+  View* last_view = NULL;
+  if (initial_parent)
+    parents.push_back(initial_parent);
+  for (size_t i = 0; i < views.size(); ++i) {
+    if (last_view && views[i]->parent_id == last_view->id()) {
+      parents.push_back(last_view);
     } else if (!parents.empty()) {
-      while (parents.back()->id() != nodes[i]->parent_id)
+      while (parents.back()->id() != views[i]->parent_id)
         parents.pop_back();
     }
-    Node* node = AddNodeToViewManager(
+    View* view = AddViewToViewManager(
         client,
         !parents.empty() ? parents.back() : NULL,
-        nodes[i]->node_id,
-        nodes[i]->view_id,
-        nodes[i]->bounds.To<gfx::Rect>());
-    if (!last_node)
-      root = node;
-    last_node = node;
+        views[i]->view_id,
+        views[i]->bounds.To<gfx::Rect>());
+    if (!last_view)
+      root = view;
+    last_view = view;
   }
   return root;
 }
 
-// Responsible for removing a root from the ViewManager when that node is
+// Responsible for removing a root from the ViewManager when that view is
 // destroyed.
-class RootObserver : public NodeObserver {
+class RootObserver : public ViewObserver {
  public:
-  explicit RootObserver(Node* root) : root_(root) {}
+  explicit RootObserver(View* root) : root_(root) {}
   virtual ~RootObserver() {}
 
  private:
-  // Overridden from NodeObserver:
-  virtual void OnNodeDestroy(Node* node,
-                             DispositionChangePhase phase) OVERRIDE {
-    DCHECK_EQ(node, root_);
-    if (phase != NodeObserver::DISPOSITION_CHANGED)
-      return;
+  // Overridden from ViewObserver:
+  virtual void OnViewDestroyed(View* view) OVERRIDE {
+    DCHECK_EQ(view, root_);
     static_cast<ViewManagerClientImpl*>(
-        NodePrivate(root_).view_manager())->RemoveRoot(root_);
+        ViewPrivate(root_).view_manager())->RemoveRoot(root_);
+    view->RemoveObserver(this);
     delete this;
   }
 
-  Node* root_;
+  View* root_;
 
   DISALLOW_COPY_AND_ASSIGN(RootObserver);
 };
 
-class ViewManagerTransaction {
- public:
-  virtual ~ViewManagerTransaction() {}
-
-  void Commit() {
-    DCHECK(!committed_);
-    DoCommit();
-    committed_ = true;
-  }
-
-  bool committed() const { return committed_; }
-
- protected:
-  explicit ViewManagerTransaction(ViewManagerClientImpl* client)
-      : committed_(false),
-        client_(client) {
-  }
-
-  // Overridden to perform transaction-specific commit actions.
-  virtual void DoCommit() = 0;
-
-  // Overridden to perform transaction-specific cleanup on commit ack from the
-  // service.
-  virtual void DoActionCompleted(bool success) = 0;
-
-  ViewManagerService* service() { return client_->service_; }
-
-  Id GetAndAdvanceNextServerChangeId() {
-    return client_->next_server_change_id_++;
-  }
-
-  base::Callback<void(bool)> ActionCompletedCallback() {
-    return base::Bind(&ViewManagerTransaction::OnActionCompleted,
-                      base::Unretained(this));
-  }
-
- private:
-  // General callback to be used for commits to the service.
-  void OnActionCompleted(bool success) {
-    DCHECK(success);
-    DoActionCompleted(success);
-    client_->RemoveFromPendingQueue(this);
-  }
-
-  bool committed_;
-  ViewManagerClientImpl* client_;
-
-  DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
-};
-
-class CreateViewTransaction : public ViewManagerTransaction {
- public:
-  CreateViewTransaction(Id view_id, ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        view_id_(view_id) {}
-  virtual ~CreateViewTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->CreateView(view_id_, ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): failure.
-  }
-
-  const Id view_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(CreateViewTransaction);
-};
-
-class DestroyViewTransaction : public ViewManagerTransaction {
- public:
-  DestroyViewTransaction(Id view_id, ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        view_id_(view_id) {}
-  virtual ~DestroyViewTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->DeleteView(view_id_, ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
-
-  const Id view_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(DestroyViewTransaction);
-};
-
-class CreateNodeTransaction : public ViewManagerTransaction {
- public:
-  CreateNodeTransaction(Id node_id, ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        node_id_(node_id) {}
-  virtual ~CreateNodeTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->CreateNode(node_id_, ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): Failure means we tried to create with an extant id for this
-    //             connection. It also could mean we tried to do something
-    //             invalid, or we tried applying a change out of order. Figure
-    //             out what to do.
-  }
-
-  const Id node_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(CreateNodeTransaction);
-};
-
-class DestroyNodeTransaction : public ViewManagerTransaction {
- public:
-  DestroyNodeTransaction(Id node_id, ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        node_id_(node_id) {}
-  virtual ~DestroyNodeTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->DeleteNode(node_id_,
-                          GetAndAdvanceNextServerChangeId(),
-                          ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
-
-  const Id node_id_;
-  DISALLOW_COPY_AND_ASSIGN(DestroyNodeTransaction);
-};
-
-class AddChildTransaction : public ViewManagerTransaction {
- public:
-  AddChildTransaction(Id child_id,
-                      Id parent_id,
-                      ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        child_id_(child_id),
-        parent_id_(parent_id) {}
-  virtual ~AddChildTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->AddNode(parent_id_,
-                       child_id_,
-                       GetAndAdvanceNextServerChangeId(),
-                       ActionCompletedCallback());
-  }
-
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
-
-  const Id child_id_;
-  const Id parent_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(AddChildTransaction);
-};
-
-class RemoveChildTransaction : public ViewManagerTransaction {
- public:
-  RemoveChildTransaction(Id child_id, ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        child_id_(child_id) {}
-  virtual ~RemoveChildTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->RemoveNodeFromParent(
-        child_id_,
-        GetAndAdvanceNextServerChangeId(),
-        ActionCompletedCallback());
-  }
-
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
-
-  const Id child_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(RemoveChildTransaction);
-};
-
-class ReorderNodeTransaction : public ViewManagerTransaction {
- public:
-  ReorderNodeTransaction(Id node_id,
-                         Id relative_id,
-                         OrderDirection direction,
-                         ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        node_id_(node_id),
-        relative_id_(relative_id),
-        direction_(direction) {}
-  virtual ~ReorderNodeTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->ReorderNode(node_id_,
-                           relative_id_,
-                           direction_,
-                           GetAndAdvanceNextServerChangeId(),
-                           ActionCompletedCallback());
-  }
-
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
-
-  const Id node_id_;
-  const Id relative_id_;
-  const OrderDirection direction_;
-
-  DISALLOW_COPY_AND_ASSIGN(ReorderNodeTransaction);
-};
-
-class SetActiveViewTransaction : public ViewManagerTransaction {
- public:
-  SetActiveViewTransaction(Id node_id,
-                           Id view_id,
-                           ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        node_id_(node_id),
-        view_id_(view_id) {}
-  virtual ~SetActiveViewTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->SetView(node_id_, view_id_, ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
-
-  const Id node_id_;
-  const Id view_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(SetActiveViewTransaction);
-};
-
-class SetBoundsTransaction : public ViewManagerTransaction {
- public:
-  SetBoundsTransaction(Id node_id,
-                       const gfx::Rect& bounds,
-                       ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        node_id_(node_id),
-        bounds_(bounds) {}
-  virtual ~SetBoundsTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->SetNodeBounds(
-        node_id_, Rect::From(bounds_), ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
-
-  const Id node_id_;
-  const gfx::Rect bounds_;
-
-  DISALLOW_COPY_AND_ASSIGN(SetBoundsTransaction);
-};
-
-class SetViewContentsTransaction : public ViewManagerTransaction {
- public:
-  SetViewContentsTransaction(Id view_id,
-                             const SkBitmap& contents,
-                             ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        view_id_(view_id),
-        contents_(contents) {}
-  virtual ~SetViewContentsTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    std::vector<unsigned char> data;
-    gfx::PNGCodec::EncodeBGRASkBitmap(contents_, false, &data);
-
-    void* memory = NULL;
-    ScopedSharedBufferHandle duped;
-    bool result = CreateMapAndDupSharedBuffer(data.size(),
-                                              &memory,
-                                              &shared_state_handle_,
-                                              &duped);
-    if (!result)
-      return;
-
-    memcpy(memory, &data[0], data.size());
-
-    service()->SetViewContents(view_id_, duped.Pass(),
-                               static_cast<uint32_t>(data.size()),
-                               ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
-
-  bool CreateMapAndDupSharedBuffer(size_t size,
-                                   void** memory,
-                                   ScopedSharedBufferHandle* handle,
-                                   ScopedSharedBufferHandle* duped) {
-    MojoResult result = CreateSharedBuffer(NULL, size, handle);
-    if (result != MOJO_RESULT_OK)
-      return false;
-    DCHECK(handle->is_valid());
-
-    result = DuplicateBuffer(handle->get(), NULL, duped);
-    if (result != MOJO_RESULT_OK)
-      return false;
-    DCHECK(duped->is_valid());
-
-    result = MapBuffer(
-        handle->get(), 0, size, memory, MOJO_MAP_BUFFER_FLAG_NONE);
-    if (result != MOJO_RESULT_OK)
-      return false;
-    DCHECK(*memory);
-
-    return true;
-  }
-
-  const Id view_id_;
-  const SkBitmap contents_;
-  ScopedSharedBufferHandle shared_state_handle_;
-
-  DISALLOW_COPY_AND_ASSIGN(SetViewContentsTransaction);
-};
-
-class EmbedTransaction : public ViewManagerTransaction {
- public:
-  EmbedTransaction(const String& url,
-                   Id node_id,
-                   ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        url_(url),
-        node_id_(node_id) {}
-  virtual ~EmbedTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    std::vector<Id> ids;
-    ids.push_back(node_id_);
-    service()->Embed(url_, Array<Id>::From(ids), ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
+bool CreateMapAndDupSharedBuffer(size_t size,
+                                  void** memory,
+                                  ScopedSharedBufferHandle* handle,
+                                  ScopedSharedBufferHandle* duped) {
+  MojoResult result = CreateSharedBuffer(NULL, size, handle);
+  if (result != MOJO_RESULT_OK)
+    return false;
+  DCHECK(handle->is_valid());
 
-  const String url_;
-  const Id node_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(EmbedTransaction);
-};
-
-class SetFocusTransaction : public ViewManagerTransaction {
- public:
-  SetFocusTransaction(Id node_id, ViewManagerClientImpl* client)
-      : ViewManagerTransaction(client),
-        node_id_(node_id) {}
-  virtual ~SetFocusTransaction() {}
-
- private:
-  // Overridden from ViewManagerTransaction:
-  virtual void DoCommit() OVERRIDE {
-    service()->SetFocus(node_id_, ActionCompletedCallback());
-  }
-  virtual void DoActionCompleted(bool success) OVERRIDE {
-    // TODO(beng): recovery?
-  }
+  result = DuplicateBuffer(handle->get(), NULL, duped);
+  if (result != MOJO_RESULT_OK)
+    return false;
+  DCHECK(duped->is_valid());
 
-  const Id node_id_;
+  result = MapBuffer(
+      handle->get(), 0, size, memory, MOJO_MAP_BUFFER_FLAG_NONE);
+  if (result != MOJO_RESULT_OK)
+    return false;
+  DCHECK(*memory);
 
-  DISALLOW_COPY_AND_ASSIGN(SetFocusTransaction);
-};
+  return true;
+}
 
-ViewManagerClientImpl::ViewManagerClientImpl(ViewManagerDelegate* delegate)
+ViewManagerClientImpl::ViewManagerClientImpl(
+    ViewManagerDelegate* delegate,
+    ApplicationConnection* app_connection)
     : connected_(false),
       connection_id_(0),
       next_id_(1),
-      next_server_change_id_(0),
-      delegate_(delegate) {}
+      delegate_(delegate),
+      window_manager_delegate_(NULL) {
+  // TODO(beng): Come up with a better way of establishing a configuration for
+  //             what the active window manager is.
+  std::string window_manager_url = "mojo:mojo_window_manager";
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch("window-manager")) {
+    window_manager_url =
+        base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+            "window-manager");
+  }
+  app_connection->ConnectToService(window_manager_url, &window_manager_);
+  window_manager_.set_client(this);
+}
 
 ViewManagerClientImpl::~ViewManagerClientImpl() {
-  while (!nodes_.empty()) {
-    IdToNodeMap::iterator it = nodes_.begin();
-    if (OwnsNode(it->second->id()))
-      it->second->Destroy();
-    else
-      nodes_.erase(it);
-  }
+  std::vector<View*> non_owned;
   while (!views_.empty()) {
     IdToViewMap::iterator it = views_.begin();
-    if (OwnsView(it->second->id()))
+    if (OwnsView(it->second->id())) {
       it->second->Destroy();
-    else
+    } else {
+      non_owned.push_back(it->second);
       views_.erase(it);
+    }
   }
-}
-
-Id ViewManagerClientImpl::CreateNode() {
-  DCHECK(connected_);
-  const Id node_id(MakeTransportId(connection_id_, ++next_id_));
-  pending_transactions_.push_back(new CreateNodeTransaction(node_id, this));
-  Sync();
-  return node_id;
-}
-
-void ViewManagerClientImpl::DestroyNode(Id node_id) {
-  DCHECK(connected_);
-  pending_transactions_.push_back(new DestroyNodeTransaction(node_id, this));
-  Sync();
+  // Delete the non-owned views last. In the typical case these are roots. The
+  // exception is the window manager, which may know aboutother random views
+  // that it doesn't own.
+  // NOTE: we manually delete as we're a friend.
+  for (size_t i = 0; i < non_owned.size(); ++i)
+    delete non_owned[i];
+  delegate_->OnViewManagerDisconnected(this);
 }
 
 Id ViewManagerClientImpl::CreateView() {
   DCHECK(connected_);
-  const Id view_id(MakeTransportId(connection_id_, ++next_id_));
-  pending_transactions_.push_back(new CreateViewTransaction(view_id, this));
-  Sync();
+  const Id view_id = MakeTransportId(connection_id_, ++next_id_);
+  service_->CreateView(view_id, ActionCompletedCallbackWithErrorCode());
   return view_id;
 }
 
 void ViewManagerClientImpl::DestroyView(Id view_id) {
   DCHECK(connected_);
-  pending_transactions_.push_back(new DestroyViewTransaction(view_id, this));
-  Sync();
+  service_->DeleteView(view_id, ActionCompletedCallback());
 }
 
-void ViewManagerClientImpl::AddChild(Id child_id,
-                                     Id parent_id) {
+void ViewManagerClientImpl::AddChild(Id child_id, Id parent_id) {
   DCHECK(connected_);
-  pending_transactions_.push_back(
-      new AddChildTransaction(child_id, parent_id, this));
-  Sync();
+  service_->AddView(parent_id, child_id, ActionCompletedCallback());
 }
 
 void ViewManagerClientImpl::RemoveChild(Id child_id, Id parent_id) {
   DCHECK(connected_);
-  pending_transactions_.push_back(new RemoveChildTransaction(child_id, this));
-  Sync();
+  service_->RemoveViewFromParent(child_id, ActionCompletedCallback());
 }
 
 void ViewManagerClientImpl::Reorder(
-    Id node_id,
-    Id relative_node_id,
+    Id view_id,
+    Id relative_view_id,
     OrderDirection direction) {
   DCHECK(connected_);
-  pending_transactions_.push_back(
-      new ReorderNodeTransaction(node_id, relative_node_id, direction, this));
-  Sync();
-}
-
-bool ViewManagerClientImpl::OwnsNode(Id id) const {
-  return HiWord(id) == connection_id_;
+  service_->ReorderView(view_id, relative_view_id, direction,
+                        ActionCompletedCallback());
 }
 
 bool ViewManagerClientImpl::OwnsView(Id id) const {
   return HiWord(id) == connection_id_;
 }
 
-void ViewManagerClientImpl::SetActiveView(Id node_id, Id view_id) {
+void ViewManagerClientImpl::SetBounds(Id view_id, const gfx::Rect& bounds) {
   DCHECK(connected_);
-  pending_transactions_.push_back(
-      new SetActiveViewTransaction(node_id, view_id, this));
-  Sync();
-}
-
-void ViewManagerClientImpl::SetBounds(Id node_id, const gfx::Rect& bounds) {
-  DCHECK(connected_);
-  pending_transactions_.push_back(
-      new SetBoundsTransaction(node_id, bounds, this));
-  Sync();
+  service_->SetViewBounds(view_id, Rect::From(bounds),
+                          ActionCompletedCallback());
 }
 
 void ViewManagerClientImpl::SetViewContents(Id view_id,
                                             const SkBitmap& contents) {
   DCHECK(connected_);
-  pending_transactions_.push_back(
-      new SetViewContentsTransaction(view_id, contents, this));
-  Sync();
+  std::vector<unsigned char> data;
+  gfx::PNGCodec::EncodeBGRASkBitmap(contents, false, &data);
+
+  void* memory = NULL;
+  ScopedSharedBufferHandle duped, shared_state_handle;
+  bool result = CreateMapAndDupSharedBuffer(data.size(),
+                                            &memory,
+                                            &shared_state_handle,
+                                            &duped);
+  if (!result)
+    return;
+
+  memcpy(memory, &data[0], data.size());
+
+  service_->SetViewContents(view_id, duped.Pass(),
+                            static_cast<uint32_t>(data.size()),
+                            ActionCompletedCallback());
 }
 
-void ViewManagerClientImpl::SetFocus(Id node_id) {
-  DCHECK(connected_);
-  pending_transactions_.push_back(new SetFocusTransaction(node_id, this));
-  Sync();
+void ViewManagerClientImpl::SetFocus(Id view_id) {
+  window_manager_->FocusWindow(view_id, ActionCompletedCallback());
 }
 
-void ViewManagerClientImpl::Embed(const String& url, Id node_id) {
+void ViewManagerClientImpl::SetVisible(Id view_id, bool visible) {
   DCHECK(connected_);
-  pending_transactions_.push_back(new EmbedTransaction(url, node_id, this));
-  Sync();
+  service_->SetViewVisibility(view_id, visible, ActionCompletedCallback());
 }
 
-void ViewManagerClientImpl::AddNode(Node* node) {
-  DCHECK(nodes_.find(node->id()) == nodes_.end());
-  nodes_[node->id()] = node;
+void ViewManagerClientImpl::Embed(const String& url, Id view_id) {
+  ServiceProviderPtr sp;
+  BindToProxy(new ServiceProviderImpl, &sp);
+  Embed(url, view_id, sp.Pass());
 }
 
-void ViewManagerClientImpl::RemoveNode(Id node_id) {
-  IdToNodeMap::iterator it = nodes_.find(node_id);
-  if (it != nodes_.end())
-    nodes_.erase(it);
+void ViewManagerClientImpl::Embed(
+    const String& url,
+    Id view_id,
+    ServiceProviderPtr service_provider) {
+  DCHECK(connected_);
+  service_->Embed(url, view_id, service_provider.Pass(),
+                  ActionCompletedCallback());
 }
 
 void ViewManagerClientImpl::AddView(View* view) {
@@ -639,19 +258,26 @@ void ViewManagerClientImpl::RemoveView(Id view_id) {
 ////////////////////////////////////////////////////////////////////////////////
 // ViewManagerClientImpl, ViewManager implementation:
 
+void ViewManagerClientImpl::SetWindowManagerDelegate(
+    WindowManagerDelegate* window_manager_delegate) {
+  CHECK(NULL != GetViewById(1));
+  CHECK(!window_manager_delegate_);
+  window_manager_delegate_ = window_manager_delegate;
+}
+
+void ViewManagerClientImpl::DispatchEvent(View* target, EventPtr event) {
+  CHECK(window_manager_delegate_);
+  service_->DispatchOnViewInputEvent(target->id(), event.Pass());
+}
+
 const std::string& ViewManagerClientImpl::GetEmbedderURL() const {
   return creator_url_;
 }
 
-const std::vector<Node*>& ViewManagerClientImpl::GetRoots() const {
+const std::vector<View*>& ViewManagerClientImpl::GetRoots() const {
   return roots_;
 }
 
-Node* ViewManagerClientImpl::GetNodeById(Id id) {
-  IdToNodeMap::const_iterator it = nodes_.find(id);
-  return it != nodes_.end() ? it->second : NULL;
-}
-
 View* ViewManagerClientImpl::GetViewById(Id id) {
   IdToViewMap::const_iterator it = views_.find(id);
   return it != views_.end() ? it->second : NULL;
@@ -667,94 +293,69 @@ void ViewManagerClientImpl::OnConnectionEstablished() {
 ////////////////////////////////////////////////////////////////////////////////
 // ViewManagerClientImpl, ViewManagerClient implementation:
 
-void ViewManagerClientImpl::OnViewManagerConnectionEstablished(
+void ViewManagerClientImpl::OnEmbed(
     ConnectionSpecificId connection_id,
     const String& creator_url,
-    Id next_server_change_id,
-    Array<NodeDataPtr> nodes) {
-  connected_ = true;
-  connection_id_ = connection_id;
-  creator_url_ = TypeConverter<String, std::string>::ConvertFrom(creator_url);
-  next_server_change_id_ = next_server_change_id;
-
-  DCHECK(pending_transactions_.empty());
-  AddRoot(BuildNodeTree(this, nodes));
-}
+    ViewDataPtr root_data,
+    InterfaceRequest<ServiceProvider> service_provider) {
+  if (!connected_) {
+    connected_ = true;
+    connection_id_ = connection_id;
+    creator_url_ = TypeConverter<String, std::string>::ConvertFrom(creator_url);
+  } else {
+    DCHECK_EQ(connection_id_, connection_id);
+    DCHECK_EQ(creator_url_, creator_url);
+  }
 
-void ViewManagerClientImpl::OnRootsAdded(Array<NodeDataPtr> nodes) {
-  AddRoot(BuildNodeTree(this, nodes));
-}
+  // A new root must not already exist as a root or be contained by an existing
+  // hierarchy visible to this view manager.
+  View* root = AddViewToViewManager(this, NULL, root_data->view_id,
+                                    root_data->bounds.To<gfx::Rect>());
+  roots_.push_back(root);
+  root->AddObserver(new RootObserver(root));
 
-void ViewManagerClientImpl::OnServerChangeIdAdvanced(
-    Id next_server_change_id) {
-  next_server_change_id_ = next_server_change_id;
+  // BindToRequest() binds the lifetime of |exported_services| to the pipe.
+  ServiceProviderImpl* exported_services = new ServiceProviderImpl;
+  BindToRequest(exported_services, &service_provider);
+  scoped_ptr<ServiceProvider> remote(
+      exported_services->CreateRemoteServiceProvider());
+  delegate_->OnEmbed(this, root, exported_services, remote.Pass());
 }
 
-void ViewManagerClientImpl::OnNodeBoundsChanged(Id node_id,
+void ViewManagerClientImpl::OnViewBoundsChanged(Id view_id,
                                                 RectPtr old_bounds,
                                                 RectPtr new_bounds) {
-  Node* node = GetNodeById(node_id);
-  NodePrivate(node).LocalSetBounds(old_bounds.To<gfx::Rect>(),
+  View* view = GetViewById(view_id);
+  ViewPrivate(view).LocalSetBounds(old_bounds.To<gfx::Rect>(),
                                    new_bounds.To<gfx::Rect>());
 }
 
-void ViewManagerClientImpl::OnNodeHierarchyChanged(
-    Id node_id,
+void ViewManagerClientImpl::OnViewHierarchyChanged(
+    Id view_id,
     Id new_parent_id,
     Id old_parent_id,
-    Id server_change_id,
-    mojo::Array<NodeDataPtr> nodes) {
-  next_server_change_id_ = server_change_id + 1;
+    mojo::Array<ViewDataPtr> views) {
+  View* initial_parent = views.size() ?
+      GetViewById(views[0]->parent_id) : NULL;
 
-  BuildNodeTree(this, nodes);
+  BuildViewTree(this, views, initial_parent);
 
-  Node* new_parent = GetNodeById(new_parent_id);
-  Node* old_parent = GetNodeById(old_parent_id);
-  Node* node = GetNodeById(node_id);
+  View* new_parent = GetViewById(new_parent_id);
+  View* old_parent = GetViewById(old_parent_id);
+  View* view = GetViewById(view_id);
   if (new_parent)
-    NodePrivate(new_parent).LocalAddChild(node);
+    ViewPrivate(new_parent).LocalAddChild(view);
   else
-    NodePrivate(old_parent).LocalRemoveChild(node);
-}
-
-void ViewManagerClientImpl::OnNodeReordered(Id node_id,
-                                            Id relative_node_id,
-                                            OrderDirection direction,
-                                            Id server_change_id) {
-  next_server_change_id_ = server_change_id + 1;
-
-  Node* node = GetNodeById(node_id);
-  Node* relative_node = GetNodeById(relative_node_id);
-  if (node && relative_node) {
-    NodePrivate(node).LocalReorder(relative_node, direction);
-  }
-}
-
-void ViewManagerClientImpl::OnNodeDeleted(Id node_id, Id server_change_id) {
-  next_server_change_id_ = server_change_id + 1;
-
-  Node* node = GetNodeById(node_id);
-  if (node)
-    NodePrivate(node).LocalDestroy();
+    ViewPrivate(old_parent).LocalRemoveChild(view);
 }
 
-void ViewManagerClientImpl::OnNodeViewReplaced(Id node_id,
-                                               Id new_view_id,
-                                               Id old_view_id) {
-  Node* node = GetNodeById(node_id);
-  View* new_view = GetViewById(new_view_id);
-  if (!new_view && new_view_id != 0) {
-    // This client wasn't aware of this View until now.
-    new_view = ViewPrivate::LocalCreate();
-    ViewPrivate private_view(new_view);
-    private_view.set_view_manager(this);
-    private_view.set_id(new_view_id);
-    private_view.set_node(node);
-    AddView(new_view);
-  }
-  View* old_view = GetViewById(old_view_id);
-  DCHECK_EQ(old_view, node->active_view());
-  NodePrivate(node).LocalSetActiveView(new_view);
+void ViewManagerClientImpl::OnViewReordered(Id view_id,
+                                            Id relative_view_id,
+                                            OrderDirection direction) {
+  View* view = GetViewById(view_id);
+  View* relative_view = GetViewById(relative_view_id);
+  if (view && relative_view)
+    ViewPrivate(view).LocalReorder(relative_view, direction);
 }
 
 void ViewManagerClientImpl::OnViewDeleted(Id view_id) {
@@ -776,66 +377,72 @@ void ViewManagerClientImpl::OnViewInputEvent(
   ack_callback.Run();
 }
 
-void ViewManagerClientImpl::DispatchOnViewInputEvent(Id view_id,
-                                                     EventPtr event) {
-  // For now blindly bounce the message back to the server. Doing this means the
-  // event is sent to the correct target (|view_id|).
-  // Note: This function is only invoked on the window manager.
-  service_->DispatchOnViewInputEvent(view_id, event.Pass());
+void ViewManagerClientImpl::Embed(
+    const String& url,
+    InterfaceRequest<ServiceProvider> service_provider) {
+  window_manager_delegate_->Embed(url, service_provider.Pass());
+}
+
+void ViewManagerClientImpl::DispatchOnViewInputEvent(EventPtr event) {
+  if (window_manager_delegate_)
+    window_manager_delegate_->DispatchEvent(event.Pass());
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// ViewManagerClientImpl, private:
+// ViewManagerClientImpl, WindowManagerClient implementation:
 
-void ViewManagerClientImpl::Sync() {
-  // The service connection may not be set up yet. OnConnectionEstablished()
-  // will schedule another sync when it is.
-  if (!connected_)
-    return;
+void ViewManagerClientImpl::OnWindowManagerReady() {}
 
-  Transactions::const_iterator it = pending_transactions_.begin();
-  for (; it != pending_transactions_.end(); ++it) {
-    if (!(*it)->committed())
-      (*it)->Commit();
+void ViewManagerClientImpl::OnCaptureChanged(Id old_capture_view_id,
+                                             Id new_capture_view_id) {}
+
+void ViewManagerClientImpl::OnFocusChanged(Id old_focused_view_id,
+                                           Id new_focused_view_id) {
+  View* focused = GetViewById(new_focused_view_id);
+  View* blurred = GetViewById(old_focused_view_id);
+  if (blurred) {
+    FOR_EACH_OBSERVER(ViewObserver,
+                      *ViewPrivate(blurred).observers(),
+                      OnViewFocusChanged(focused, blurred));
+  }
+  if (focused) {
+    FOR_EACH_OBSERVER(ViewObserver,
+                      *ViewPrivate(focused).observers(),
+                      OnViewFocusChanged(focused, blurred));
   }
 }
 
-void ViewManagerClientImpl::RemoveFromPendingQueue(
-    ViewManagerTransaction* transaction) {
-  DCHECK_EQ(transaction, pending_transactions_.front());
-  pending_transactions_.erase(pending_transactions_.begin());
-  if (pending_transactions_.empty() && !changes_acked_callback_.is_null())
-    changes_acked_callback_.Run();
-}
+void ViewManagerClientImpl::OnActiveWindowChanged(Id old_focused_window,
+                                                  Id new_focused_window) {}
 
-void ViewManagerClientImpl::AddRoot(Node* root) {
-  // A new root must not already exist as a root or be contained by an existing
-  // hierarchy visible to this view manager.
-  std::vector<Node*>::const_iterator it = roots_.begin();
-  for (; it != roots_.end(); ++it) {
-    if (*it == root || (*it)->Contains(root))
-      return;
-  }
-  roots_.push_back(root);
-  root->AddObserver(new RootObserver(root));
-  delegate_->OnRootAdded(this, root);
-}
+////////////////////////////////////////////////////////////////////////////////
+// ViewManagerClientImpl, private:
 
-void ViewManagerClientImpl::RemoveRoot(Node* root) {
-  std::vector<Node*>::iterator it =
+void ViewManagerClientImpl::RemoveRoot(View* root) {
+  std::vector<View*>::iterator it =
       std::find(roots_.begin(), roots_.end(), root);
   if (it != roots_.end())
     roots_.erase(it);
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// ViewManager, public:
+void ViewManagerClientImpl::OnActionCompleted(bool success) {
+  if (!change_acked_callback_.is_null())
+    change_acked_callback_.Run();
+}
+
+void ViewManagerClientImpl::OnActionCompletedWithErrorCode(ErrorCode code) {
+  OnActionCompleted(code == ERROR_CODE_NONE);
+}
+
+base::Callback<void(bool)> ViewManagerClientImpl::ActionCompletedCallback() {
+  return base::Bind(&ViewManagerClientImpl::OnActionCompleted,
+                    base::Unretained(this));
+}
 
-// static
-void ViewManager::Create(Application* application,
-                         ViewManagerDelegate* delegate) {
-  application->AddService<ViewManagerClientImpl>(delegate);
+base::Callback<void(ErrorCode)>
+    ViewManagerClientImpl::ActionCompletedCallbackWithErrorCode() {
+  return base::Bind(&ViewManagerClientImpl::OnActionCompletedWithErrorCode,
+                    base::Unretained(this));
 }
 
-}  // namespace view_manager
 }  // namespace mojo