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