view_manager_service_impl.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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 "mojo/services/public/cpp/geometry/geometry_type_converters.h"
9#include "mojo/services/public/cpp/input_events/input_events_type_converters.h"
10#include "mojo/services/view_manager/default_access_policy.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 "mojo/services/view_manager/window_manager_access_policy.h"
15#include "third_party/skia/include/core/SkBitmap.h"
16#include "ui/aura/window.h"
17#include "ui/gfx/codec/png_codec.h"
18
19namespace mojo {
20namespace service {
21
22ViewManagerServiceImpl::ViewManagerServiceImpl(
23    RootNodeManager* root_node_manager,
24    ConnectionSpecificId creator_id,
25    const std::string& creator_url,
26    const std::string& url,
27    const NodeId& root_id)
28    : root_node_manager_(root_node_manager),
29      id_(root_node_manager_->GetAndAdvanceNextConnectionId()),
30      url_(url),
31      creator_id_(creator_id),
32      creator_url_(creator_url),
33      delete_on_connection_error_(false) {
34  CHECK(GetNode(root_id));
35  roots_.insert(NodeIdToTransportId(root_id));
36  if (root_id == RootNodeId())
37    access_policy_.reset(new WindowManagerAccessPolicy(id_, this));
38  else
39    access_policy_.reset(new DefaultAccessPolicy(id_, this));
40}
41
42ViewManagerServiceImpl::~ViewManagerServiceImpl() {
43  // Delete any views we created.
44  while (!view_map_.empty()) {
45    bool result = DeleteViewImpl(this, view_map_.begin()->second);
46    DCHECK(result);
47  }
48
49  // Ditto the nodes.
50  if (!node_map_.empty()) {
51    RootNodeManager::ScopedChange change(this, root_node_manager_, true);
52    while (!node_map_.empty())
53      delete node_map_.begin()->second;
54  }
55
56  root_node_manager_->RemoveConnection(this);
57}
58
59const Node* ViewManagerServiceImpl::GetNode(const NodeId& id) const {
60  if (id_ == id.connection_id) {
61    NodeMap::const_iterator i = node_map_.find(id.node_id);
62    return i == node_map_.end() ? NULL : i->second;
63  }
64  return root_node_manager_->GetNode(id);
65}
66
67const View* ViewManagerServiceImpl::GetView(const ViewId& id) const {
68  if (id_ == id.connection_id) {
69    ViewMap::const_iterator i = view_map_.find(id.view_id);
70    return i == view_map_.end() ? NULL : i->second;
71  }
72  return root_node_manager_->GetView(id);
73}
74
75bool ViewManagerServiceImpl::HasRoot(const NodeId& id) const {
76  return roots_.find(NodeIdToTransportId(id)) != roots_.end();
77}
78
79void ViewManagerServiceImpl::OnViewManagerServiceImplDestroyed(
80    ConnectionSpecificId id) {
81  if (creator_id_ == id)
82    creator_id_ = kInvalidConnectionId;
83}
84
85void ViewManagerServiceImpl::ProcessNodeBoundsChanged(
86    const Node* node,
87    const gfx::Rect& old_bounds,
88    const gfx::Rect& new_bounds,
89    bool originated_change) {
90  if (originated_change || !IsNodeKnown(node))
91    return;
92  client()->OnNodeBoundsChanged(NodeIdToTransportId(node->id()),
93                                Rect::From(old_bounds),
94                                Rect::From(new_bounds));
95}
96
97void ViewManagerServiceImpl::ProcessNodeHierarchyChanged(
98    const Node* node,
99    const Node* new_parent,
100    const Node* old_parent,
101    bool originated_change) {
102  if (originated_change && !IsNodeKnown(node) && new_parent &&
103      IsNodeKnown(new_parent)) {
104    std::vector<const Node*> unused;
105    GetUnknownNodesFrom(node, &unused);
106  }
107  if (originated_change || root_node_manager_->is_processing_delete_node() ||
108      root_node_manager_->DidConnectionMessageClient(id_)) {
109    return;
110  }
111
112  if (!access_policy_->ShouldNotifyOnHierarchyChange(
113          node, &new_parent, &old_parent)) {
114    return;
115  }
116  // Inform the client of any new nodes and update the set of nodes we know
117  // about.
118  std::vector<const Node*> to_send;
119  if (!IsNodeKnown(node))
120    GetUnknownNodesFrom(node, &to_send);
121  const NodeId new_parent_id(new_parent ? new_parent->id() : NodeId());
122  const NodeId old_parent_id(old_parent ? old_parent->id() : NodeId());
123  client()->OnNodeHierarchyChanged(NodeIdToTransportId(node->id()),
124                                   NodeIdToTransportId(new_parent_id),
125                                   NodeIdToTransportId(old_parent_id),
126                                   NodesToNodeDatas(to_send));
127  root_node_manager_->OnConnectionMessagedClient(id_);
128}
129
130void ViewManagerServiceImpl::ProcessNodeReorder(const Node* node,
131                                                const Node* relative_node,
132                                                OrderDirection direction,
133                                                bool originated_change) {
134  if (originated_change || !IsNodeKnown(node) || !IsNodeKnown(relative_node))
135    return;
136
137  client()->OnNodeReordered(NodeIdToTransportId(node->id()),
138                            NodeIdToTransportId(relative_node->id()),
139                            direction);
140}
141
142void ViewManagerServiceImpl::ProcessNodeViewReplaced(
143    const Node* node,
144    const View* new_view,
145    const View* old_view,
146    bool originated_change) {
147  if (originated_change || !IsNodeKnown(node) ||
148      root_node_manager_->is_processing_delete_node()) {
149    return;
150  }
151  const Id new_view_id = new_view ?
152      access_policy_->GetViewIdToSend(node, new_view) : 0;
153  const Id old_view_id = old_view ?
154      access_policy_->GetViewIdToSend(node, old_view) : 0;
155  client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()),
156                               new_view_id, old_view_id);
157}
158
159void ViewManagerServiceImpl::ProcessNodeDeleted(const NodeId& node,
160                                                bool originated_change) {
161  node_map_.erase(node.node_id);
162
163  const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0;
164  roots_.erase(NodeIdToTransportId(node));
165
166  if (originated_change)
167    return;
168
169  if (in_known) {
170    client()->OnNodeDeleted(NodeIdToTransportId(node));
171    root_node_manager_->OnConnectionMessagedClient(id_);
172  }
173}
174
175void ViewManagerServiceImpl::ProcessViewDeleted(const ViewId& view,
176                                                bool originated_change) {
177  if (!originated_change && access_policy_->ShouldSendViewDeleted(view))
178    client()->OnViewDeleted(ViewIdToTransportId(view));
179}
180
181void ViewManagerServiceImpl::ProcessFocusChanged(const Node* focused_node,
182                                                 const Node* blurred_node,
183                                                 bool originated_change) {
184  if (originated_change)
185    return;
186
187  // TODO(sky): this should not notify all clients.
188  Id focused_id = 0;
189  Id blurred_id = 0;
190  if (focused_node && IsNodeKnown(focused_node))
191    focused_id = NodeIdToTransportId(focused_node->id());
192  if (blurred_node && IsNodeKnown(blurred_node))
193    blurred_id = NodeIdToTransportId(blurred_node->id());
194
195  if (focused_id != 0 || blurred_id != 0)
196    client()->OnFocusChanged(focused_id, blurred_id);
197}
198
199void ViewManagerServiceImpl::OnConnectionError() {
200  if (delete_on_connection_error_)
201    delete this;
202}
203
204bool ViewManagerServiceImpl::IsNodeKnown(const Node* node) const {
205  return known_nodes_.count(NodeIdToTransportId(node->id())) > 0;
206}
207
208bool ViewManagerServiceImpl::CanReorderNode(const Node* node,
209                                            const Node* relative_node,
210                                            OrderDirection direction) const {
211  if (!node || !relative_node)
212    return false;
213
214  const Node* parent = node->GetParent();
215  if (!parent || parent != relative_node->GetParent())
216    return false;
217
218  if (!access_policy_->CanReorderNode(node, relative_node, direction))
219    return false;
220
221  std::vector<const Node*> children = parent->GetChildren();
222  const size_t child_i =
223      std::find(children.begin(), children.end(), node) - children.begin();
224  const size_t target_i =
225      std::find(children.begin(), children.end(), relative_node) -
226      children.begin();
227  if ((direction == ORDER_DIRECTION_ABOVE && child_i == target_i + 1) ||
228      (direction == ORDER_DIRECTION_BELOW && child_i + 1 == target_i)) {
229    return false;
230  }
231
232  return true;
233}
234
235bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source,
236                                            Node* node) {
237  DCHECK(node);
238  DCHECK_EQ(node->id().connection_id, id_);
239  RootNodeManager::ScopedChange change(source, root_node_manager_, true);
240  delete node;
241  return true;
242}
243
244bool ViewManagerServiceImpl::DeleteViewImpl(ViewManagerServiceImpl* source,
245                                            View* view) {
246  DCHECK(view);
247  DCHECK_EQ(view->id().connection_id, id_);
248  RootNodeManager::ScopedChange change(source, root_node_manager_, false);
249  if (view->node())
250    view->node()->SetView(NULL);
251  view_map_.erase(view->id().view_id);
252  const ViewId view_id(view->id());
253  delete view;
254  root_node_manager_->ProcessViewDeleted(view_id);
255  return true;
256}
257
258bool ViewManagerServiceImpl::SetViewImpl(Node* node, View* view) {
259  DCHECK(node);  // CanSetView() should have verified node exists.
260  RootNodeManager::ScopedChange change(this, root_node_manager_, false);
261  node->SetView(view);
262  return true;
263}
264
265void ViewManagerServiceImpl::GetUnknownNodesFrom(
266    const Node* node,
267    std::vector<const Node*>* nodes) {
268  if (IsNodeKnown(node) || !access_policy_->CanGetNodeTree(node))
269    return;
270  nodes->push_back(node);
271  known_nodes_.insert(NodeIdToTransportId(node->id()));
272  if (!access_policy_->CanDescendIntoNodeForNodeTree(node))
273    return;
274  std::vector<const Node*> children(node->GetChildren());
275  for (size_t i = 0 ; i < children.size(); ++i)
276    GetUnknownNodesFrom(children[i], nodes);
277}
278
279void ViewManagerServiceImpl::RemoveFromKnown(const Node* node,
280                                             std::vector<Node*>* local_nodes) {
281  if (node->id().connection_id == id_) {
282    if (local_nodes)
283      local_nodes->push_back(GetNode(node->id()));
284    return;
285  }
286  known_nodes_.erase(NodeIdToTransportId(node->id()));
287  std::vector<const Node*> children = node->GetChildren();
288  for (size_t i = 0; i < children.size(); ++i)
289    RemoveFromKnown(children[i], local_nodes);
290}
291
292void ViewManagerServiceImpl::AddRoot(const NodeId& node_id) {
293  const Id transport_node_id(NodeIdToTransportId(node_id));
294  CHECK(roots_.count(transport_node_id) == 0);
295
296  CHECK_EQ(creator_id_, node_id.connection_id);
297  roots_.insert(transport_node_id);
298  const Node* node = GetNode(node_id);
299  CHECK(node);
300  std::vector<const Node*> to_send;
301  if (!IsNodeKnown(node)) {
302    GetUnknownNodesFrom(node, &to_send);
303  } else {
304    // Even though the connection knows about the new root we need to tell it
305    // |node| is now a root.
306    to_send.push_back(node);
307  }
308
309  client()->OnEmbed(id_, creator_url_, NodeToNodeData(to_send.front()));
310  root_node_manager_->OnConnectionMessagedClient(id_);
311}
312
313void ViewManagerServiceImpl::RemoveRoot(const NodeId& node_id) {
314  const Id transport_node_id(NodeIdToTransportId(node_id));
315  CHECK(roots_.count(transport_node_id) > 0);
316
317  roots_.erase(transport_node_id);
318
319  // No need to do anything if we created the node.
320  if (node_id.connection_id == id_)
321    return;
322
323  client()->OnNodeDeleted(transport_node_id);
324  root_node_manager_->OnConnectionMessagedClient(id_);
325
326  // This connection no longer knows about the node. Unparent any nodes that
327  // were parented to nodes in the root.
328  std::vector<Node*> local_nodes;
329  RemoveFromKnown(GetNode(node_id), &local_nodes);
330  for (size_t i = 0; i < local_nodes.size(); ++i)
331    local_nodes[i]->GetParent()->Remove(local_nodes[i]);
332}
333
334void ViewManagerServiceImpl::RemoveChildrenAsPartOfEmbed(
335    const NodeId& node_id) {
336  Node* node = GetNode(node_id);
337  CHECK(node);
338  CHECK(node->id().connection_id == node_id.connection_id);
339  std::vector<Node*> children = node->GetChildren();
340  for (size_t i = 0; i < children.size(); ++i)
341    node->Remove(children[i]);
342}
343
344Array<NodeDataPtr> ViewManagerServiceImpl::NodesToNodeDatas(
345    const std::vector<const Node*>& nodes) {
346  Array<NodeDataPtr> array(nodes.size());
347  for (size_t i = 0; i < nodes.size(); ++i)
348    array[i] = NodeToNodeData(nodes[i]).Pass();
349  return array.Pass();
350}
351
352NodeDataPtr ViewManagerServiceImpl::NodeToNodeData(const Node* node) {
353  DCHECK(IsNodeKnown(node));
354  const Node* parent = node->GetParent();
355  // If the parent isn't known, it means the parent is not visible to us (not
356  // in roots), and should not be sent over.
357  if (parent && !IsNodeKnown(parent))
358    parent = NULL;
359  NodeDataPtr node_data(NodeData::New());
360  node_data->parent_id = NodeIdToTransportId(parent ? parent->id() : NodeId());
361  node_data->node_id = NodeIdToTransportId(node->id());
362  // TODO(sky): should the id only be sent if known?
363  node_data->view_id =
364    ViewIdToTransportId(node->view() ? node->view()->id() : ViewId());
365  node_data->bounds = Rect::From(node->bounds());
366  return node_data.Pass();
367}
368
369void ViewManagerServiceImpl::GetNodeTreeImpl(
370    const Node* node,
371    std::vector<const Node*>* nodes) const {
372  DCHECK(node);
373
374  if (!access_policy_->CanGetNodeTree(node))
375    return;
376
377  nodes->push_back(node);
378
379  if (!access_policy_->CanDescendIntoNodeForNodeTree(node))
380    return;
381
382  std::vector<const Node*> children(node->GetChildren());
383  for (size_t i = 0 ; i < children.size(); ++i)
384    GetNodeTreeImpl(children[i], nodes);
385}
386
387void ViewManagerServiceImpl::CreateNode(
388    Id transport_node_id,
389    const Callback<void(ErrorCode)>& callback) {
390  const NodeId node_id(NodeIdFromTransportId(transport_node_id));
391  ErrorCode error_code = ERROR_CODE_NONE;
392  if (node_id.connection_id != id_) {
393    error_code = ERROR_CODE_ILLEGAL_ARGUMENT;
394  } else if (node_map_.find(node_id.node_id) != node_map_.end()) {
395    error_code = ERROR_CODE_VALUE_IN_USE;
396  } else {
397    node_map_[node_id.node_id] = new Node(root_node_manager_, node_id);
398    known_nodes_.insert(transport_node_id);
399  }
400  callback.Run(error_code);
401}
402
403void ViewManagerServiceImpl::DeleteNode(
404    Id transport_node_id,
405    const Callback<void(bool)>& callback) {
406  Node* node = GetNode(NodeIdFromTransportId(transport_node_id));
407  bool success = false;
408  if (node && access_policy_->CanDeleteNode(node)) {
409    ViewManagerServiceImpl* connection = root_node_manager_->GetConnection(
410        node->id().connection_id);
411    success = connection && connection->DeleteNodeImpl(this, node);
412  }
413  callback.Run(success);
414}
415
416void ViewManagerServiceImpl::AddNode(
417    Id parent_id,
418    Id child_id,
419    const Callback<void(bool)>& callback) {
420  bool success = false;
421  Node* parent = GetNode(NodeIdFromTransportId(parent_id));
422  Node* child = GetNode(NodeIdFromTransportId(child_id));
423  if (parent && child && child->GetParent() != parent &&
424      !child->Contains(parent) && access_policy_->CanAddNode(parent, child)) {
425    success = true;
426    RootNodeManager::ScopedChange change(this, root_node_manager_, false);
427    parent->Add(child);
428  }
429  callback.Run(success);
430}
431
432void ViewManagerServiceImpl::RemoveNodeFromParent(
433    Id node_id,
434    const Callback<void(bool)>& callback) {
435  bool success = false;
436  Node* node = GetNode(NodeIdFromTransportId(node_id));
437  if (node && node->GetParent() &&
438      access_policy_->CanRemoveNodeFromParent(node)) {
439    success = true;
440    RootNodeManager::ScopedChange change(this, root_node_manager_, false);
441    node->GetParent()->Remove(node);
442  }
443  callback.Run(success);
444}
445
446void ViewManagerServiceImpl::ReorderNode(Id node_id,
447                                         Id relative_node_id,
448                                         OrderDirection direction,
449                                         const Callback<void(bool)>& callback) {
450  bool success = false;
451  Node* node = GetNode(NodeIdFromTransportId(node_id));
452  Node* relative_node = GetNode(NodeIdFromTransportId(relative_node_id));
453  if (CanReorderNode(node, relative_node, direction)) {
454    success = true;
455    RootNodeManager::ScopedChange change(this, root_node_manager_, false);
456    node->GetParent()->Reorder(node, relative_node, direction);
457    root_node_manager_->ProcessNodeReorder(node, relative_node, direction);
458  }
459  callback.Run(success);
460}
461
462void ViewManagerServiceImpl::GetNodeTree(
463    Id node_id,
464    const Callback<void(Array<NodeDataPtr>)>& callback) {
465  Node* node = GetNode(NodeIdFromTransportId(node_id));
466  std::vector<const Node*> nodes;
467  if (node) {
468    GetNodeTreeImpl(node, &nodes);
469    // TODO(sky): this should map in nodes that weren't none.
470  }
471  callback.Run(NodesToNodeDatas(nodes));
472}
473
474void ViewManagerServiceImpl::CreateView(
475    Id transport_view_id,
476    const Callback<void(bool)>& callback) {
477  const ViewId view_id(ViewIdFromTransportId(transport_view_id));
478  if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) {
479    callback.Run(false);
480    return;
481  }
482  view_map_[view_id.view_id] = new View(view_id);
483  callback.Run(true);
484}
485
486void ViewManagerServiceImpl::DeleteView(Id transport_view_id,
487                                        const Callback<void(bool)>& callback) {
488  View* view = GetView(ViewIdFromTransportId(transport_view_id));
489  bool did_delete = false;
490  if (view && access_policy_->CanDeleteView(view)) {
491    ViewManagerServiceImpl* connection = root_node_manager_->GetConnection(
492        view->id().connection_id);
493    did_delete = (connection && connection->DeleteViewImpl(this, view));
494  }
495  callback.Run(did_delete);
496}
497
498void ViewManagerServiceImpl::SetView(Id transport_node_id,
499                                     Id transport_view_id,
500                                     const Callback<void(bool)>& callback) {
501  Node* node = GetNode(NodeIdFromTransportId(transport_node_id));
502  View* view = GetView(ViewIdFromTransportId(transport_view_id));
503  const bool valid_view = view ||
504      ViewIdFromTransportId(transport_node_id) != ViewId();
505  callback.Run(valid_view && node && access_policy_->CanSetView(node, view) &&
506               SetViewImpl(node, view));
507}
508
509void ViewManagerServiceImpl::SetViewContents(
510    Id view_id,
511    ScopedSharedBufferHandle buffer,
512    uint32_t buffer_size,
513    const Callback<void(bool)>& callback) {
514  // TODO(sky): add coverage of not being able to set for random view.
515  View* view = GetView(ViewIdFromTransportId(view_id));
516  if (!view || !access_policy_->CanSetViewContents(view)) {
517    callback.Run(false);
518    return;
519  }
520  void* handle_data;
521  if (MapBuffer(buffer.get(), 0, buffer_size, &handle_data,
522                MOJO_MAP_BUFFER_FLAG_NONE) != MOJO_RESULT_OK) {
523    callback.Run(false);
524    return;
525  }
526  SkBitmap bitmap;
527  gfx::PNGCodec::Decode(static_cast<const unsigned char*>(handle_data),
528                        buffer_size, &bitmap);
529  view->SetBitmap(bitmap);
530  UnmapBuffer(handle_data);
531  callback.Run(true);
532}
533
534void ViewManagerServiceImpl::SetFocus(Id node_id,
535                                      const Callback<void(bool)> & callback) {
536  bool success = false;
537  Node* node = GetNode(NodeIdFromTransportId(node_id));
538  if (node && access_policy_->CanSetFocus(node)) {
539    success = true;
540    node->window()->Focus();
541  }
542  callback.Run(success);
543}
544
545void ViewManagerServiceImpl::SetNodeBounds(
546    Id node_id,
547    RectPtr bounds,
548    const Callback<void(bool)>& callback) {
549  Node* node = GetNode(NodeIdFromTransportId(node_id));
550  const bool success = node && access_policy_->CanSetNodeBounds(node);
551  if (success) {
552    RootNodeManager::ScopedChange change(this, root_node_manager_, false);
553    gfx::Rect old_bounds = node->window()->bounds();
554    node->window()->SetBounds(bounds.To<gfx::Rect>());
555  }
556  callback.Run(success);
557}
558
559void ViewManagerServiceImpl::SetNodeVisibility(
560    Id transport_node_id,
561    bool visible,
562    const Callback<void(bool)>& callback) {
563  Node* node = GetNode(NodeIdFromTransportId(transport_node_id));
564  const bool success = node && node->IsVisible() != visible &&
565      access_policy_->CanChangeNodeVisibility(node);
566  if (success) {
567    DCHECK(node);
568    node->SetVisible(visible);
569  }
570  // TODO(sky): need to notify of visibility changes.
571  callback.Run(success);
572}
573
574void ViewManagerServiceImpl::Embed(const String& url,
575                                   Id transport_node_id,
576                                   const Callback<void(bool)>& callback) {
577  if (NodeIdFromTransportId(transport_node_id) == InvalidNodeId()) {
578    root_node_manager_->EmbedRoot(url);
579    callback.Run(true);
580    return;
581  }
582  const Node* node = GetNode(NodeIdFromTransportId(transport_node_id));
583  bool success = node && access_policy_->CanEmbed(node);
584  if (success) {
585    // Only allow a node to be the root for one connection.
586    const NodeId node_id(NodeIdFromTransportId(transport_node_id));
587    ViewManagerServiceImpl* connection_by_url =
588        root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>());
589    ViewManagerServiceImpl* connection_with_node_as_root =
590        root_node_manager_->GetConnectionWithRoot(node_id);
591    if ((connection_by_url != connection_with_node_as_root ||
592         (!connection_by_url && !connection_with_node_as_root)) &&
593        (!connection_by_url || !connection_by_url->HasRoot(node_id))) {
594      RootNodeManager::ScopedChange change(this, root_node_manager_, true);
595      RemoveChildrenAsPartOfEmbed(node_id);
596      // Never message the originating connection.
597      root_node_manager_->OnConnectionMessagedClient(id_);
598      if (connection_with_node_as_root)
599        connection_with_node_as_root->RemoveRoot(node_id);
600      if (connection_by_url)
601        connection_by_url->AddRoot(node_id);
602      else
603        root_node_manager_->Embed(id_, url, transport_node_id);
604    } else {
605      success = false;
606    }
607  }
608  callback.Run(success);
609}
610
611void ViewManagerServiceImpl::DispatchOnViewInputEvent(Id transport_view_id,
612                                                      EventPtr event) {
613  // We only allow the WM to dispatch events. At some point this function will
614  // move to a separate interface and the check can go away.
615  if (id_ != kWindowManagerConnection)
616    return;
617
618  const ViewId view_id(ViewIdFromTransportId(transport_view_id));
619  ViewManagerServiceImpl* connection = root_node_manager_->GetConnection(
620      view_id.connection_id);
621  if (connection) {
622    connection->client()->OnViewInputEvent(
623        transport_view_id,
624        event.Pass(),
625        base::Bind(&base::DoNothing));
626  }
627}
628
629void ViewManagerServiceImpl::OnConnectionEstablished() {
630  root_node_manager_->AddConnection(this);
631
632  std::vector<const Node*> to_send;
633  for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i)
634    GetUnknownNodesFrom(GetNode(NodeIdFromTransportId(*i)), &to_send);
635
636  client()->OnEmbed(id_, creator_url_, NodeToNodeData(to_send.front()));
637}
638
639const base::hash_set<Id>&
640ViewManagerServiceImpl::GetRootsForAccessPolicy() const {
641  return roots_;
642}
643
644bool ViewManagerServiceImpl::IsNodeKnownForAccessPolicy(
645    const Node* node) const {
646  return IsNodeKnown(node);
647}
648
649bool ViewManagerServiceImpl::IsNodeRootOfAnotherConnectionForAccessPolicy(
650    const Node* node) const {
651  ViewManagerServiceImpl* connection =
652      root_node_manager_->GetConnectionWithRoot(node->id());
653  return connection && connection != this;
654}
655
656}  // namespace service
657}  // namespace mojo
658