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