Home | History | Annotate | Download | only in view_manager
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "mojo/services/view_manager/view_manager_service_impl.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/stl_util.h"
      9 #include "mojo/services/public/cpp/geometry/geometry_type_converters.h"
     10 #include "mojo/services/public/cpp/input_events/input_events_type_converters.h"
     11 #include "mojo/services/view_manager/node.h"
     12 #include "mojo/services/view_manager/root_node_manager.h"
     13 #include "mojo/services/view_manager/view.h"
     14 #include "third_party/skia/include/core/SkBitmap.h"
     15 #include "ui/aura/window.h"
     16 #include "ui/gfx/codec/png_codec.h"
     17 
     18 namespace mojo {
     19 namespace view_manager {
     20 namespace service {
     21 namespace {
     22 
     23 // Places |node| in |nodes| and recurses through the children.
     24 void GetDescendants(const Node* node, std::vector<const Node*>* nodes) {
     25   if (!node)
     26     return;
     27 
     28   nodes->push_back(node);
     29 
     30   std::vector<const Node*> children(node->GetChildren());
     31   for (size_t i = 0 ; i < children.size(); ++i)
     32     GetDescendants(children[i], nodes);
     33 }
     34 
     35 }  // namespace
     36 
     37 ViewManagerServiceImpl::ViewManagerServiceImpl(
     38     RootNodeManager* root_node_manager,
     39     ConnectionSpecificId creator_id,
     40     const std::string& creator_url,
     41     const std::string& url)
     42     : root_node_manager_(root_node_manager),
     43       id_(root_node_manager_->GetAndAdvanceNextConnectionId()),
     44       url_(url),
     45       creator_id_(creator_id),
     46       creator_url_(creator_url),
     47       delete_on_connection_error_(false) {
     48 }
     49 
     50 ViewManagerServiceImpl::~ViewManagerServiceImpl() {
     51   // Delete any views we own.
     52   while (!view_map_.empty()) {
     53     bool result = DeleteViewImpl(this, view_map_.begin()->second->id());
     54     DCHECK(result);
     55   }
     56 
     57   // We're about to destroy all our nodes. Detach any views from them.
     58   for (NodeMap::iterator i = node_map_.begin(); i != node_map_.end(); ++i) {
     59     if (i->second->view()) {
     60       bool result = SetViewImpl(i->second, ViewId());
     61       DCHECK(result);
     62     }
     63   }
     64 
     65   if (!node_map_.empty()) {
     66     RootNodeManager::ScopedChange change(
     67         this, root_node_manager_,
     68         RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true);
     69     while (!node_map_.empty()) {
     70       scoped_ptr<Node> node(node_map_.begin()->second);
     71       Node* parent = node->GetParent();
     72       const NodeId node_id(node->id());
     73       if (parent)
     74         parent->Remove(node.get());
     75       root_node_manager_->ProcessNodeDeleted(node_id);
     76       node_map_.erase(NodeIdToTransportId(node_id));
     77     }
     78   }
     79 
     80   root_node_manager_->RemoveConnection(this);
     81 }
     82 
     83 const Node* ViewManagerServiceImpl::GetNode(const NodeId& id) const {
     84   if (id_ == id.connection_id) {
     85     NodeMap::const_iterator i = node_map_.find(id.node_id);
     86     return i == node_map_.end() ? NULL : i->second;
     87   }
     88   return root_node_manager_->GetNode(id);
     89 }
     90 
     91 const View* ViewManagerServiceImpl::GetView(const ViewId& id) const {
     92   if (id_ == id.connection_id) {
     93     ViewMap::const_iterator i = view_map_.find(id.view_id);
     94     return i == view_map_.end() ? NULL : i->second;
     95   }
     96   return root_node_manager_->GetView(id);
     97 }
     98 
     99 void ViewManagerServiceImpl::SetRoots(const Array<Id>& node_ids) {
    100   DCHECK(roots_.empty());
    101   NodeIdSet roots;
    102   for (size_t i = 0; i < node_ids.size(); ++i) {
    103     DCHECK(GetNode(NodeIdFromTransportId(node_ids[i])));
    104     roots.insert(node_ids[i]);
    105   }
    106   roots_.swap(roots);
    107 }
    108 
    109 void ViewManagerServiceImpl::OnViewManagerServiceImplDestroyed(
    110     ConnectionSpecificId id) {
    111   if (creator_id_ == id)
    112     creator_id_ = kRootConnection;
    113 }
    114 
    115 void ViewManagerServiceImpl::ProcessNodeBoundsChanged(
    116     const Node* node,
    117     const gfx::Rect& old_bounds,
    118     const gfx::Rect& new_bounds,
    119     bool originated_change) {
    120   if (originated_change)
    121     return;
    122   Id node_id = NodeIdToTransportId(node->id());
    123   if (known_nodes_.count(node_id) > 0) {
    124     client()->OnNodeBoundsChanged(node_id,
    125                                   Rect::From(old_bounds),
    126                                   Rect::From(new_bounds));
    127   }
    128 }
    129 
    130 void ViewManagerServiceImpl::ProcessNodeHierarchyChanged(
    131     const Node* node,
    132     const Node* new_parent,
    133     const Node* old_parent,
    134     Id server_change_id,
    135     bool originated_change) {
    136   if (known_nodes_.count(NodeIdToTransportId(node->id())) > 0) {
    137     if (originated_change)
    138       return;
    139     if (node->id().connection_id != id_ && !IsNodeDescendantOfRoots(node)) {
    140       // Node was a descendant of roots and is no longer, treat it as though the
    141       // node was deleted.
    142       RemoveFromKnown(node);
    143       client()->OnNodeDeleted(NodeIdToTransportId(node->id()),
    144                               server_change_id);
    145       root_node_manager_->OnConnectionMessagedClient(id_);
    146       return;
    147     }
    148   }
    149 
    150   if (originated_change || root_node_manager_->is_processing_delete_node())
    151     return;
    152   std::vector<const Node*> to_send;
    153   if (!ShouldNotifyOnHierarchyChange(node, &new_parent, &old_parent,
    154                                      &to_send)) {
    155     if (root_node_manager_->IsProcessingChange()) {
    156       client()->OnServerChangeIdAdvanced(
    157           root_node_manager_->next_server_change_id() + 1);
    158     }
    159     return;
    160   }
    161   const NodeId new_parent_id(new_parent ? new_parent->id() : NodeId());
    162   const NodeId old_parent_id(old_parent ? old_parent->id() : NodeId());
    163   DCHECK((node->id().connection_id == id_) ||
    164          (roots_.count(NodeIdToTransportId(node->id())) > 0) ||
    165          (new_parent && IsNodeDescendantOfRoots(new_parent)) ||
    166          (old_parent && IsNodeDescendantOfRoots(old_parent)));
    167   client()->OnNodeHierarchyChanged(NodeIdToTransportId(node->id()),
    168                                    NodeIdToTransportId(new_parent_id),
    169                                    NodeIdToTransportId(old_parent_id),
    170                                    server_change_id,
    171                                    NodesToNodeDatas(to_send));
    172 }
    173 
    174 void ViewManagerServiceImpl::ProcessNodeReorder(const Node* node,
    175                                                 const Node* relative_node,
    176                                                 OrderDirection direction,
    177                                                 Id server_change_id,
    178                                                 bool originated_change) {
    179   if (originated_change ||
    180       !known_nodes_.count(NodeIdToTransportId(node->id())) ||
    181       !known_nodes_.count(NodeIdToTransportId(relative_node->id()))) {
    182     return;
    183   }
    184 
    185   client()->OnNodeReordered(NodeIdToTransportId(node->id()),
    186                             NodeIdToTransportId(relative_node->id()),
    187                             direction,
    188                             server_change_id);
    189 }
    190 
    191 void ViewManagerServiceImpl::ProcessNodeViewReplaced(
    192     const Node* node,
    193     const View* new_view,
    194     const View* old_view,
    195     bool originated_change) {
    196   if (originated_change || !known_nodes_.count(NodeIdToTransportId(node->id())))
    197     return;
    198   const Id new_view_id = new_view ?
    199       ViewIdToTransportId(new_view->id()) : 0;
    200   const Id old_view_id = old_view ?
    201       ViewIdToTransportId(old_view->id()) : 0;
    202   client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()),
    203                                new_view_id, old_view_id);
    204 }
    205 
    206 void ViewManagerServiceImpl::ProcessNodeDeleted(const NodeId& node,
    207                                                 Id server_change_id,
    208                                                 bool originated_change) {
    209   const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0;
    210   const bool in_roots = roots_.erase(NodeIdToTransportId(node)) > 0;
    211 
    212   if (in_roots && roots_.empty())
    213     roots_.insert(NodeIdToTransportId(InvalidNodeId()));
    214 
    215   if (originated_change)
    216     return;
    217 
    218   if (in_known) {
    219     client()->OnNodeDeleted(NodeIdToTransportId(node), server_change_id);
    220     root_node_manager_->OnConnectionMessagedClient(id_);
    221   } else if (root_node_manager_->IsProcessingChange() &&
    222              !root_node_manager_->DidConnectionMessageClient(id_)) {
    223     client()->OnServerChangeIdAdvanced(
    224         root_node_manager_->next_server_change_id() + 1);
    225     root_node_manager_->OnConnectionMessagedClient(id_);
    226   }
    227 }
    228 
    229 void ViewManagerServiceImpl::ProcessViewDeleted(const ViewId& view,
    230                                                 bool originated_change) {
    231   if (originated_change)
    232     return;
    233   client()->OnViewDeleted(ViewIdToTransportId(view));
    234 }
    235 
    236 void ViewManagerServiceImpl::OnConnectionError() {
    237   if (delete_on_connection_error_)
    238     delete this;
    239 }
    240 
    241 bool ViewManagerServiceImpl::CanRemoveNodeFromParent(const Node* node) const {
    242   if (!node)
    243     return false;
    244 
    245   const Node* parent = node->GetParent();
    246   if (!parent)
    247     return false;
    248 
    249   // Always allow the remove if there are no roots. Otherwise the remove is
    250   // allowed if the parent is a descendant of the roots, or the node and its
    251   // parent were created by this connection. We explicitly disallow removal of
    252   // the node from its parent if the parent isn't visible to this connection
    253   // (not in roots).
    254   return (roots_.empty() ||
    255           (IsNodeDescendantOfRoots(parent) ||
    256            (node->id().connection_id == id_ &&
    257             parent->id().connection_id == id_)));
    258 }
    259 
    260 bool ViewManagerServiceImpl::CanAddNode(const Node* parent,
    261                                         const Node* child) const {
    262   if (!parent || !child)
    263     return false;  // Both nodes must be valid.
    264 
    265   if (child->GetParent() == parent || child->Contains(parent))
    266     return false;  // Would result in an invalid hierarchy.
    267 
    268   if (roots_.empty())
    269     return true;  // No restriction if there are no roots.
    270 
    271   if (!IsNodeDescendantOfRoots(parent) && parent->id().connection_id != id_)
    272     return false;  // |parent| is not visible to this connection.
    273 
    274   // Allow the add if the child is already a descendant of the roots or was
    275   // created by this connection.
    276   return (IsNodeDescendantOfRoots(child) || child->id().connection_id == id_);
    277 }
    278 
    279 bool ViewManagerServiceImpl::CanReorderNode(const Node* node,
    280                                             const Node* relative_node,
    281                                             OrderDirection direction) const {
    282   if (!node || !relative_node)
    283     return false;
    284 
    285   if (node->id().connection_id != id_)
    286     return false;
    287 
    288   const Node* parent = node->GetParent();
    289   if (!parent || parent != relative_node->GetParent())
    290     return false;
    291 
    292   if (known_nodes_.count(NodeIdToTransportId(parent->id())) == 0)
    293     return false;
    294 
    295   std::vector<const Node*> children = parent->GetChildren();
    296   const size_t child_i =
    297       std::find(children.begin(), children.end(), node) - children.begin();
    298   const size_t target_i =
    299       std::find(children.begin(), children.end(), relative_node) -
    300       children.begin();
    301   if ((direction == ORDER_ABOVE && child_i == target_i + 1) ||
    302       (direction == ORDER_BELOW && child_i + 1 == target_i)) {
    303     return false;
    304   }
    305 
    306   return true;
    307 }
    308 
    309 bool ViewManagerServiceImpl::CanDeleteNode(const NodeId& node_id) const {
    310   return node_id.connection_id == id_;
    311 }
    312 
    313 bool ViewManagerServiceImpl::CanDeleteView(const ViewId& view_id) const {
    314   return view_id.connection_id == id_;
    315 }
    316 
    317 bool ViewManagerServiceImpl::CanSetView(const Node* node,
    318                                         const ViewId& view_id) const {
    319   if (!node || !IsNodeDescendantOfRoots(node))
    320     return false;
    321 
    322   const View* view = GetView(view_id);
    323   return (view && view_id.connection_id == id_) || view_id == ViewId();
    324 }
    325 
    326 bool ViewManagerServiceImpl::CanSetFocus(const Node* node) const {
    327   // TODO(beng): security.
    328   return true;
    329 }
    330 
    331 bool ViewManagerServiceImpl::CanGetNodeTree(const Node* node) const {
    332   return node &&
    333       (IsNodeDescendantOfRoots(node) || node->id().connection_id == id_);
    334 }
    335 
    336 bool ViewManagerServiceImpl::CanEmbed(
    337     const mojo::Array<uint32_t>& node_ids) const {
    338   for (size_t i = 0; i < node_ids.size(); ++i) {
    339     const Node* node = GetNode(NodeIdFromTransportId(node_ids[i]));
    340     if (!node || node->id().connection_id != id_)
    341       return false;
    342   }
    343   return node_ids.size() > 0;
    344 }
    345 
    346 bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source,
    347                                             const NodeId& node_id) {
    348   DCHECK_EQ(node_id.connection_id, id_);
    349   Node* node = GetNode(node_id);
    350   if (!node)
    351     return false;
    352   RootNodeManager::ScopedChange change(
    353       source, root_node_manager_,
    354       RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true);
    355   if (node->GetParent())
    356     node->GetParent()->Remove(node);
    357   std::vector<Node*> children(node->GetChildren());
    358   for (size_t i = 0; i < children.size(); ++i)
    359     node->Remove(children[i]);
    360   DCHECK(node->GetChildren().empty());
    361   node_map_.erase(node_id.node_id);
    362   delete node;
    363   node = NULL;
    364   root_node_manager_->ProcessNodeDeleted(node_id);
    365   return true;
    366 }
    367 
    368 bool ViewManagerServiceImpl::DeleteViewImpl(ViewManagerServiceImpl* source,
    369                                             const ViewId& view_id) {
    370   DCHECK_EQ(view_id.connection_id, id_);
    371   View* view = GetView(view_id);
    372   if (!view)
    373     return false;
    374   RootNodeManager::ScopedChange change(
    375       source, root_node_manager_,
    376       RootNodeManager::CHANGE_TYPE_DONT_ADVANCE_SERVER_CHANGE_ID, false);
    377   if (view->node())
    378     view->node()->SetView(NULL);
    379   view_map_.erase(view_id.view_id);
    380   // Make a copy of |view_id| as once we delete view |view_id| may no longer be
    381   // valid.
    382   const ViewId view_id_copy(view_id);
    383   delete view;
    384   root_node_manager_->ProcessViewDeleted(view_id_copy);
    385   return true;
    386 }
    387 
    388 bool ViewManagerServiceImpl::SetViewImpl(Node* node, const ViewId& view_id) {
    389   DCHECK(node);  // CanSetView() should have verified node exists.
    390   View* view = GetView(view_id);
    391   RootNodeManager::ScopedChange change(
    392       this, root_node_manager_,
    393       RootNodeManager::CHANGE_TYPE_DONT_ADVANCE_SERVER_CHANGE_ID, false);
    394   node->SetView(view);
    395 
    396   // TODO(sky): this is temporary, need a real focus API.
    397   if (view && root_node_manager_->root()->Contains(node))
    398     node->window()->Focus();
    399 
    400   return true;
    401 }
    402 
    403 void ViewManagerServiceImpl::GetUnknownNodesFrom(
    404     const Node* node,
    405     std::vector<const Node*>* nodes) {
    406   const Id transport_id = NodeIdToTransportId(node->id());
    407   if (known_nodes_.count(transport_id) == 1)
    408     return;
    409   nodes->push_back(node);
    410   known_nodes_.insert(transport_id);
    411   std::vector<const Node*> children(node->GetChildren());
    412   for (size_t i = 0 ; i < children.size(); ++i)
    413     GetUnknownNodesFrom(children[i], nodes);
    414 }
    415 
    416 void ViewManagerServiceImpl::RemoveFromKnown(const Node* node) {
    417   if (node->id().connection_id == id_)
    418     return;
    419   known_nodes_.erase(NodeIdToTransportId(node->id()));
    420   std::vector<const Node*> children = node->GetChildren();
    421   for (size_t i = 0; i < children.size(); ++i)
    422     RemoveFromKnown(children[i]);
    423 }
    424 
    425 bool ViewManagerServiceImpl::AddRoots(
    426     const std::vector<Id>& node_ids) {
    427   std::vector<const Node*> to_send;
    428   bool did_add_root = false;
    429   for (size_t i = 0; i < node_ids.size(); ++i) {
    430     CHECK_EQ(creator_id_, NodeIdFromTransportId(node_ids[i]).connection_id);
    431     if (roots_.count(node_ids[i]) > 0)
    432       continue;
    433 
    434     did_add_root = true;
    435     roots_.insert(node_ids[i]);
    436     Node* node = GetNode(NodeIdFromTransportId(node_ids[i]));
    437     DCHECK(node);
    438     if (known_nodes_.count(node_ids[i]) == 0) {
    439       GetUnknownNodesFrom(node, &to_send);
    440     } else {
    441       // Even though the connection knows about the new root we need to tell it
    442       // |node| is now a root.
    443       to_send.push_back(node);
    444     }
    445   }
    446 
    447   if (!did_add_root)
    448     return false;
    449 
    450   client()->OnRootsAdded(NodesToNodeDatas(to_send));
    451   return true;
    452 }
    453 
    454 bool ViewManagerServiceImpl::IsNodeDescendantOfRoots(const Node* node) const {
    455   if (roots_.empty())
    456     return true;
    457   if (!node)
    458     return false;
    459   const Id invalid_node_id =
    460       NodeIdToTransportId(InvalidNodeId());
    461   for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) {
    462     if (*i == invalid_node_id)
    463       continue;
    464     const Node* root = GetNode(NodeIdFromTransportId(*i));
    465     DCHECK(root);
    466     if (root->Contains(node))
    467       return true;
    468   }
    469   return false;
    470 }
    471 
    472 bool ViewManagerServiceImpl::ShouldNotifyOnHierarchyChange(
    473     const Node* node,
    474     const Node** new_parent,
    475     const Node** old_parent,
    476     std::vector<const Node*>* to_send) {
    477   // If the node is not in |roots_| or was never known to this connection then
    478   // don't notify the client about it.
    479   if (node->id().connection_id != id_ &&
    480       known_nodes_.count(NodeIdToTransportId(node->id())) == 0 &&
    481       !IsNodeDescendantOfRoots(node)) {
    482     return false;
    483   }
    484   if (!IsNodeDescendantOfRoots(*new_parent))
    485     *new_parent = NULL;
    486   if (!IsNodeDescendantOfRoots(*old_parent))
    487     *old_parent = NULL;
    488 
    489   if (*new_parent) {
    490     // On getting a new parent we may need to communicate new nodes to the
    491     // client. We do that in the following cases:
    492     // . New parent is a descendant of the roots. In this case the client
    493     //   already knows all ancestors, so we only have to communicate descendants
    494     //   of node the client doesn't know about.
    495     // . If the client knew about the parent, we have to do the same.
    496     // . If the client knows about the node and is added to a tree the client
    497     //   doesn't know about we have to communicate from the root down (the
    498     //   client is learning about a new root).
    499     if (root_node_manager_->root()->Contains(*new_parent) ||
    500         known_nodes_.count(NodeIdToTransportId((*new_parent)->id()))) {
    501       GetUnknownNodesFrom(node, to_send);
    502       return true;
    503     }
    504     // If parent wasn't known we have to communicate from the root down.
    505     if (known_nodes_.count(NodeIdToTransportId(node->id()))) {
    506       // No need to check against |roots_| as client should always know it's
    507       // |roots_|.
    508       GetUnknownNodesFrom((*new_parent)->GetRoot(), to_send);
    509       return true;
    510     }
    511   }
    512   // Otherwise only communicate the change if the node was known. We shouldn't
    513   // need to communicate any nodes on a remove.
    514   return known_nodes_.count(NodeIdToTransportId(node->id())) > 0;
    515 }
    516 
    517 Array<NodeDataPtr> ViewManagerServiceImpl::NodesToNodeDatas(
    518     const std::vector<const Node*>& nodes) {
    519   Array<NodeDataPtr> array(nodes.size());
    520   for (size_t i = 0; i < nodes.size(); ++i) {
    521     const Node* node = nodes[i];
    522     DCHECK(known_nodes_.count(NodeIdToTransportId(node->id())) > 0);
    523     const Node* parent = node->GetParent();
    524     // If the parent isn't known, it means the parent is not visible to us (not
    525     // in roots), and should not be sent over.
    526     if (parent && known_nodes_.count(NodeIdToTransportId(parent->id())) == 0)
    527       parent = NULL;
    528     NodeDataPtr inode(NodeData::New());
    529     inode->parent_id = NodeIdToTransportId(parent ? parent->id() : NodeId());
    530     inode->node_id = NodeIdToTransportId(node->id());
    531     inode->view_id =
    532         ViewIdToTransportId(node->view() ? node->view()->id() : ViewId());
    533     inode->bounds = Rect::From(node->bounds());
    534     array[i] = inode.Pass();
    535   }
    536   return array.Pass();
    537 }
    538 
    539 void ViewManagerServiceImpl::CreateNode(
    540     Id transport_node_id,
    541     const Callback<void(bool)>& callback) {
    542   const NodeId node_id(NodeIdFromTransportId(transport_node_id));
    543   if (node_id.connection_id != id_ ||
    544       node_map_.find(node_id.node_id) != node_map_.end()) {
    545     callback.Run(false);
    546     return;
    547   }
    548   node_map_[node_id.node_id] = new Node(this, node_id);
    549   known_nodes_.insert(transport_node_id);
    550   callback.Run(true);
    551 }
    552 
    553 void ViewManagerServiceImpl::DeleteNode(
    554     Id transport_node_id,
    555     Id server_change_id,
    556     const Callback<void(bool)>& callback) {
    557   const NodeId node_id(NodeIdFromTransportId(transport_node_id));
    558   bool success = false;
    559   if (server_change_id == root_node_manager_->next_server_change_id() &&
    560       CanDeleteNode(node_id)) {
    561     ViewManagerServiceImpl* connection = root_node_manager_->GetConnection(
    562         node_id.connection_id);
    563     success = connection && connection->DeleteNodeImpl(this, node_id);
    564   }
    565   callback.Run(success);
    566 }
    567 
    568 void ViewManagerServiceImpl::AddNode(
    569     Id parent_id,
    570     Id child_id,
    571     Id server_change_id,
    572     const Callback<void(bool)>& callback) {
    573   bool success = false;
    574   if (server_change_id == root_node_manager_->next_server_change_id()) {
    575     Node* parent = GetNode(NodeIdFromTransportId(parent_id));
    576     Node* child = GetNode(NodeIdFromTransportId(child_id));
    577     if (CanAddNode(parent, child)) {
    578       success = true;
    579       RootNodeManager::ScopedChange change(
    580           this, root_node_manager_,
    581           RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, false);
    582       parent->Add(child);
    583     }
    584   }
    585   callback.Run(success);
    586 }
    587 
    588 void ViewManagerServiceImpl::RemoveNodeFromParent(
    589     Id node_id,
    590     Id server_change_id,
    591     const Callback<void(bool)>& callback) {
    592   bool success = false;
    593   if (server_change_id == root_node_manager_->next_server_change_id()) {
    594     Node* node = GetNode(NodeIdFromTransportId(node_id));
    595     if (CanRemoveNodeFromParent(node)) {
    596       success = true;
    597       RootNodeManager::ScopedChange change(
    598           this, root_node_manager_,
    599           RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, false);
    600       node->GetParent()->Remove(node);
    601     }
    602   }
    603   callback.Run(success);
    604 }
    605 
    606 void ViewManagerServiceImpl::ReorderNode(Id node_id,
    607                                          Id relative_node_id,
    608                                          OrderDirection direction,
    609                                          Id server_change_id,
    610                                          const Callback<void(bool)>& callback) {
    611   bool success = false;
    612   if (server_change_id == root_node_manager_->next_server_change_id()) {
    613     Node* node = GetNode(NodeIdFromTransportId(node_id));
    614     Node* relative_node = GetNode(NodeIdFromTransportId(relative_node_id));
    615     if (CanReorderNode(node, relative_node, direction)) {
    616       success = true;
    617       RootNodeManager::ScopedChange change(
    618           this, root_node_manager_,
    619           RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, false);
    620       node->GetParent()->Reorder(node, relative_node, direction);
    621       root_node_manager_->ProcessNodeReorder(node, relative_node, direction);
    622     }
    623   }
    624   callback.Run(success);
    625 }
    626 
    627 void ViewManagerServiceImpl::GetNodeTree(
    628     Id node_id,
    629     const Callback<void(Array<NodeDataPtr>)>& callback) {
    630   Node* node = GetNode(NodeIdFromTransportId(node_id));
    631   std::vector<const Node*> nodes;
    632   if (CanGetNodeTree(node)) {
    633     GetDescendants(node, &nodes);
    634     for (size_t i = 0; i < nodes.size(); ++i)
    635       known_nodes_.insert(NodeIdToTransportId(nodes[i]->id()));
    636   }
    637   callback.Run(NodesToNodeDatas(nodes));
    638 }
    639 
    640 void ViewManagerServiceImpl::CreateView(
    641     Id transport_view_id,
    642     const Callback<void(bool)>& callback) {
    643   const ViewId view_id(ViewIdFromTransportId(transport_view_id));
    644   if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) {
    645     callback.Run(false);
    646     return;
    647   }
    648   view_map_[view_id.view_id] = new View(view_id);
    649   callback.Run(true);
    650 }
    651 
    652 void ViewManagerServiceImpl::DeleteView(
    653     Id transport_view_id,
    654     const Callback<void(bool)>& callback) {
    655   const ViewId view_id(ViewIdFromTransportId(transport_view_id));
    656   bool did_delete = CanDeleteView(view_id);
    657   if (did_delete) {
    658     ViewManagerServiceImpl* connection = root_node_manager_->GetConnection(
    659         view_id.connection_id);
    660     did_delete = (connection && connection->DeleteViewImpl(this, view_id));
    661   }
    662   callback.Run(did_delete);
    663 }
    664 
    665 void ViewManagerServiceImpl::SetView(Id transport_node_id,
    666                                      Id transport_view_id,
    667                                      const Callback<void(bool)>& callback) {
    668   Node* node = GetNode(NodeIdFromTransportId(transport_node_id));
    669   const ViewId view_id(ViewIdFromTransportId(transport_view_id));
    670   callback.Run(CanSetView(node, view_id) && SetViewImpl(node, view_id));
    671 }
    672 
    673 void ViewManagerServiceImpl::SetViewContents(
    674     Id view_id,
    675     ScopedSharedBufferHandle buffer,
    676     uint32_t buffer_size,
    677     const Callback<void(bool)>& callback) {
    678   View* view = GetView(ViewIdFromTransportId(view_id));
    679   if (!view) {
    680     callback.Run(false);
    681     return;
    682   }
    683   void* handle_data;
    684   if (MapBuffer(buffer.get(), 0, buffer_size, &handle_data,
    685                 MOJO_MAP_BUFFER_FLAG_NONE) != MOJO_RESULT_OK) {
    686     callback.Run(false);
    687     return;
    688   }
    689   SkBitmap bitmap;
    690   gfx::PNGCodec::Decode(static_cast<const unsigned char*>(handle_data),
    691                         buffer_size, &bitmap);
    692   view->SetBitmap(bitmap);
    693   UnmapBuffer(handle_data);
    694   callback.Run(true);
    695 }
    696 
    697 void ViewManagerServiceImpl::SetFocus(Id node_id,
    698                                       const Callback<void(bool)> & callback) {
    699   bool success = false;
    700   Node* node = GetNode(NodeIdFromTransportId(node_id));
    701   if (CanSetFocus(node)) {
    702     success = true;
    703     node->window()->Focus();
    704   }
    705   callback.Run(success);
    706 }
    707 
    708 void ViewManagerServiceImpl::SetNodeBounds(
    709     Id node_id,
    710     RectPtr bounds,
    711     const Callback<void(bool)>& callback) {
    712   if (NodeIdFromTransportId(node_id).connection_id != id_) {
    713     callback.Run(false);
    714     return;
    715   }
    716 
    717   Node* node = GetNode(NodeIdFromTransportId(node_id));
    718   if (!node) {
    719     callback.Run(false);
    720     return;
    721   }
    722 
    723   RootNodeManager::ScopedChange change(
    724       this, root_node_manager_,
    725       RootNodeManager::CHANGE_TYPE_DONT_ADVANCE_SERVER_CHANGE_ID, false);
    726   gfx::Rect old_bounds = node->window()->bounds();
    727   node->window()->SetBounds(bounds.To<gfx::Rect>());
    728   root_node_manager_->ProcessNodeBoundsChanged(
    729       node, old_bounds, bounds.To<gfx::Rect>());
    730   callback.Run(true);
    731 }
    732 
    733 void ViewManagerServiceImpl::Embed(const String& url,
    734                                    Array<uint32_t> node_ids,
    735                                    const Callback<void(bool)>& callback) {
    736   bool success = CanEmbed(node_ids);
    737   if (success) {
    738     // We may already have this connection, if so reuse it.
    739     ViewManagerServiceImpl* existing_connection =
    740         root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>());
    741     if (existing_connection)
    742       success = existing_connection->AddRoots(node_ids.storage());
    743     else
    744       root_node_manager_->Embed(id_, url, node_ids);
    745   }
    746   callback.Run(success);
    747 }
    748 
    749 void ViewManagerServiceImpl::DispatchOnViewInputEvent(Id transport_view_id,
    750                                                       EventPtr event) {
    751   // We only allow the WM to dispatch events. At some point this function will
    752   // move to a separate interface and the check can go away.
    753   if (id_ != kWindowManagerConnection)
    754     return;
    755 
    756   const ViewId view_id(ViewIdFromTransportId(transport_view_id));
    757   ViewManagerServiceImpl* connection = root_node_manager_->GetConnection(
    758       view_id.connection_id);
    759   if (connection)
    760     connection->client()->OnViewInputEvent(
    761         transport_view_id,
    762         event.Pass(),
    763         base::Bind(&base::DoNothing));
    764 }
    765 
    766 void ViewManagerServiceImpl::OnNodeHierarchyChanged(const Node* node,
    767                                                     const Node* new_parent,
    768                                                     const Node* old_parent) {
    769   root_node_manager_->ProcessNodeHierarchyChanged(node, new_parent, old_parent);
    770 }
    771 
    772 void ViewManagerServiceImpl::OnNodeViewReplaced(const Node* node,
    773                                                 const View* new_view,
    774                                                 const View* old_view) {
    775   root_node_manager_->ProcessNodeViewReplaced(node, new_view, old_view);
    776 }
    777 
    778 void ViewManagerServiceImpl::OnViewInputEvent(const View* view,
    779                                               const ui::Event* event) {
    780   root_node_manager_->DispatchViewInputEventToWindowManager(view, event);
    781 }
    782 
    783 void ViewManagerServiceImpl::OnConnectionEstablished() {
    784   root_node_manager_->AddConnection(this);
    785 
    786   std::vector<const Node*> to_send;
    787   if (roots_.empty()) {
    788     GetUnknownNodesFrom(root_node_manager_->root(), &to_send);
    789   } else {
    790     for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i)
    791       GetUnknownNodesFrom(GetNode(NodeIdFromTransportId(*i)), &to_send);
    792   }
    793 
    794   client()->OnViewManagerConnectionEstablished(
    795       id_,
    796       creator_url_,
    797       root_node_manager_->next_server_change_id(),
    798       NodesToNodeDatas(to_send));
    799 }
    800 
    801 }  // namespace service
    802 }  // namespace view_manager
    803 }  // namespace mojo
    804