OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/services/view_manager/view_manager_service_impl.h" | 5 #include "mojo/services/view_manager/view_manager_service_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "mojo/services/public/cpp/geometry/geometry_type_converters.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" | 9 #include "mojo/services/public/cpp/input_events/input_events_type_converters.h" |
10 #include "mojo/services/view_manager/node.h" | 10 #include "mojo/services/view_manager/node.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 } | 79 } |
80 | 80 |
81 const View* ViewManagerServiceImpl::GetView(const ViewId& id) const { | 81 const View* ViewManagerServiceImpl::GetView(const ViewId& id) const { |
82 if (id_ == id.connection_id) { | 82 if (id_ == id.connection_id) { |
83 ViewMap::const_iterator i = view_map_.find(id.view_id); | 83 ViewMap::const_iterator i = view_map_.find(id.view_id); |
84 return i == view_map_.end() ? NULL : i->second; | 84 return i == view_map_.end() ? NULL : i->second; |
85 } | 85 } |
86 return root_node_manager_->GetView(id); | 86 return root_node_manager_->GetView(id); |
87 } | 87 } |
88 | 88 |
| 89 bool ViewManagerServiceImpl::HasRoot(const NodeId& id) const { |
| 90 return roots_.find(NodeIdToTransportId(id)) != roots_.end(); |
| 91 } |
| 92 |
89 void ViewManagerServiceImpl::OnViewManagerServiceImplDestroyed( | 93 void ViewManagerServiceImpl::OnViewManagerServiceImplDestroyed( |
90 ConnectionSpecificId id) { | 94 ConnectionSpecificId id) { |
91 if (creator_id_ == id) | 95 if (creator_id_ == id) |
92 creator_id_ = kRootConnection; | 96 creator_id_ = kRootConnection; |
93 } | 97 } |
94 | 98 |
95 void ViewManagerServiceImpl::ProcessNodeBoundsChanged( | 99 void ViewManagerServiceImpl::ProcessNodeBoundsChanged( |
96 const Node* node, | 100 const Node* node, |
97 const gfx::Rect& old_bounds, | 101 const gfx::Rect& old_bounds, |
98 const gfx::Rect& new_bounds, | 102 const gfx::Rect& new_bounds, |
(...skipping 13 matching lines...) Expand all Loading... |
112 const Node* new_parent, | 116 const Node* new_parent, |
113 const Node* old_parent, | 117 const Node* old_parent, |
114 Id server_change_id, | 118 Id server_change_id, |
115 bool originated_change) { | 119 bool originated_change) { |
116 if (known_nodes_.count(NodeIdToTransportId(node->id())) > 0) { | 120 if (known_nodes_.count(NodeIdToTransportId(node->id())) > 0) { |
117 if (originated_change) | 121 if (originated_change) |
118 return; | 122 return; |
119 if (node->id().connection_id != id_ && !IsNodeDescendantOfRoots(node)) { | 123 if (node->id().connection_id != id_ && !IsNodeDescendantOfRoots(node)) { |
120 // Node was a descendant of roots and is no longer, treat it as though the | 124 // Node was a descendant of roots and is no longer, treat it as though the |
121 // node was deleted. | 125 // node was deleted. |
122 RemoveFromKnown(node); | 126 RemoveFromKnown(node, NULL); |
123 client()->OnNodeDeleted(NodeIdToTransportId(node->id()), | 127 client()->OnNodeDeleted(NodeIdToTransportId(node->id()), |
124 server_change_id); | 128 server_change_id); |
125 root_node_manager_->OnConnectionMessagedClient(id_); | 129 root_node_manager_->OnConnectionMessagedClient(id_); |
126 return; | 130 return; |
127 } | 131 } |
128 } | 132 } |
129 | 133 |
130 if (originated_change || root_node_manager_->is_processing_delete_node()) | 134 if (originated_change || root_node_manager_->is_processing_delete_node()) |
131 return; | 135 return; |
132 std::vector<const Node*> to_send; | 136 std::vector<const Node*> to_send; |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 const Id transport_id = NodeIdToTransportId(node->id()); | 404 const Id transport_id = NodeIdToTransportId(node->id()); |
401 if (known_nodes_.count(transport_id) == 1) | 405 if (known_nodes_.count(transport_id) == 1) |
402 return; | 406 return; |
403 nodes->push_back(node); | 407 nodes->push_back(node); |
404 known_nodes_.insert(transport_id); | 408 known_nodes_.insert(transport_id); |
405 std::vector<const Node*> children(node->GetChildren()); | 409 std::vector<const Node*> children(node->GetChildren()); |
406 for (size_t i = 0 ; i < children.size(); ++i) | 410 for (size_t i = 0 ; i < children.size(); ++i) |
407 GetUnknownNodesFrom(children[i], nodes); | 411 GetUnknownNodesFrom(children[i], nodes); |
408 } | 412 } |
409 | 413 |
410 void ViewManagerServiceImpl::RemoveFromKnown(const Node* node) { | 414 void ViewManagerServiceImpl::RemoveFromKnown(const Node* node, |
411 if (node->id().connection_id == id_) | 415 std::vector<Node*>* local_nodes) { |
| 416 if (node->id().connection_id == id_) { |
| 417 if (local_nodes) |
| 418 local_nodes->push_back(GetNode(node->id())); |
412 return; | 419 return; |
| 420 } |
413 known_nodes_.erase(NodeIdToTransportId(node->id())); | 421 known_nodes_.erase(NodeIdToTransportId(node->id())); |
414 std::vector<const Node*> children = node->GetChildren(); | 422 std::vector<const Node*> children = node->GetChildren(); |
415 for (size_t i = 0; i < children.size(); ++i) | 423 for (size_t i = 0; i < children.size(); ++i) |
416 RemoveFromKnown(children[i]); | 424 RemoveFromKnown(children[i], local_nodes); |
417 } | 425 } |
418 | 426 |
419 bool ViewManagerServiceImpl::AddRoot(Id transport_node_id) { | 427 void ViewManagerServiceImpl::AddRoot(const NodeId& node_id) { |
420 if (roots_.count(transport_node_id) > 0) | 428 const Id transport_node_id(NodeIdToTransportId(node_id)); |
421 return false; | 429 CHECK(roots_.count(transport_node_id) == 0); |
422 | 430 |
423 std::vector<const Node*> to_send; | 431 std::vector<const Node*> to_send; |
424 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | |
425 CHECK_EQ(creator_id_, node_id.connection_id); | 432 CHECK_EQ(creator_id_, node_id.connection_id); |
426 roots_.insert(transport_node_id); | 433 roots_.insert(transport_node_id); |
427 Node* node = GetNode(node_id); | 434 Node* node = GetNode(node_id); |
428 CHECK(node); | 435 CHECK(node); |
429 if (known_nodes_.count(transport_node_id) == 0) { | 436 if (known_nodes_.count(transport_node_id) == 0) { |
430 GetUnknownNodesFrom(node, &to_send); | 437 GetUnknownNodesFrom(node, &to_send); |
431 } else { | 438 } else { |
432 // Even though the connection knows about the new root we need to tell it | 439 // Even though the connection knows about the new root we need to tell it |
433 // |node| is now a root. | 440 // |node| is now a root. |
434 to_send.push_back(node); | 441 to_send.push_back(node); |
435 } | 442 } |
436 | 443 |
437 client()->OnRootAdded(NodesToNodeDatas(to_send)); | 444 client()->OnRootAdded(NodesToNodeDatas(to_send)); |
438 return true; | 445 root_node_manager_->OnConnectionMessagedClient(id_); |
| 446 } |
| 447 |
| 448 void ViewManagerServiceImpl::RemoveRoot(const NodeId& node_id) { |
| 449 const Id transport_node_id(NodeIdToTransportId(node_id)); |
| 450 CHECK(roots_.count(transport_node_id) > 0); |
| 451 |
| 452 roots_.erase(transport_node_id); |
| 453 if (roots_.empty()) |
| 454 roots_.insert(NodeIdToTransportId(InvalidNodeId())); |
| 455 |
| 456 // No need to do anything if we created the node. |
| 457 if (node_id.connection_id == id_) |
| 458 return; |
| 459 |
| 460 client()->OnNodeDeleted(transport_node_id, |
| 461 root_node_manager_->next_server_change_id()); |
| 462 root_node_manager_->OnConnectionMessagedClient(id_); |
| 463 |
| 464 // This connection no longer knows about the node. Unparent any nodes that |
| 465 // were parented to nodes in the root. |
| 466 std::vector<Node*> local_nodes; |
| 467 RemoveFromKnown(GetNode(node_id), &local_nodes); |
| 468 for (size_t i = 0; i < local_nodes.size(); ++i) |
| 469 local_nodes[i]->GetParent()->Remove(local_nodes[i]); |
439 } | 470 } |
440 | 471 |
441 bool ViewManagerServiceImpl::IsNodeDescendantOfRoots(const Node* node) const { | 472 bool ViewManagerServiceImpl::IsNodeDescendantOfRoots(const Node* node) const { |
442 if (roots_.empty()) | 473 if (roots_.empty()) |
443 return true; | 474 return true; |
444 if (!node) | 475 if (!node) |
445 return false; | 476 return false; |
446 const Id invalid_node_id = | 477 const Id invalid_node_id = |
447 NodeIdToTransportId(InvalidNodeId()); | 478 NodeIdToTransportId(InvalidNodeId()); |
448 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) { | 479 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) { |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 } | 761 } |
731 // TODO(sky): need to notify of visibility changes. | 762 // TODO(sky): need to notify of visibility changes. |
732 callback.Run(success); | 763 callback.Run(success); |
733 } | 764 } |
734 | 765 |
735 void ViewManagerServiceImpl::Embed(const String& url, | 766 void ViewManagerServiceImpl::Embed(const String& url, |
736 Id transport_node_id, | 767 Id transport_node_id, |
737 const Callback<void(bool)>& callback) { | 768 const Callback<void(bool)>& callback) { |
738 bool success = CanEmbed(transport_node_id); | 769 bool success = CanEmbed(transport_node_id); |
739 if (success) { | 770 if (success) { |
740 // We may already have this connection, if so reuse it. | 771 // Only allow a node to be the root for one connection. |
741 ViewManagerServiceImpl* existing_connection = | 772 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); |
| 773 ViewManagerServiceImpl* connection_by_url = |
742 root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>()); | 774 root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>()); |
743 if (existing_connection) | 775 ViewManagerServiceImpl* connection_with_node_as_root = |
744 success = existing_connection->AddRoot(transport_node_id); | 776 root_node_manager_->GetConnectionWithRoot(node_id); |
745 else | 777 if ((connection_by_url != connection_with_node_as_root || |
746 root_node_manager_->Embed(id_, url, transport_node_id); | 778 (!connection_by_url && !connection_with_node_as_root)) && |
| 779 (!connection_by_url || !connection_by_url->HasRoot(node_id))) { |
| 780 RootNodeManager::ScopedChange change( |
| 781 this, root_node_manager_, |
| 782 RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true); |
| 783 // Never message the originating connection. |
| 784 root_node_manager_->OnConnectionMessagedClient(id_); |
| 785 if (connection_with_node_as_root) |
| 786 connection_with_node_as_root->RemoveRoot(node_id); |
| 787 if (connection_by_url) |
| 788 connection_by_url->AddRoot(node_id); |
| 789 else |
| 790 root_node_manager_->Embed(id_, url, transport_node_id); |
| 791 change.SendServerChangeIdAdvanced(); |
| 792 } else { |
| 793 success = false; |
| 794 } |
747 } | 795 } |
748 callback.Run(success); | 796 callback.Run(success); |
749 } | 797 } |
750 | 798 |
751 void ViewManagerServiceImpl::DispatchOnViewInputEvent(Id transport_view_id, | 799 void ViewManagerServiceImpl::DispatchOnViewInputEvent(Id transport_view_id, |
752 EventPtr event) { | 800 EventPtr event) { |
753 // We only allow the WM to dispatch events. At some point this function will | 801 // We only allow the WM to dispatch events. At some point this function will |
754 // move to a separate interface and the check can go away. | 802 // move to a separate interface and the check can go away. |
755 if (id_ != kWindowManagerConnection) | 803 if (id_ != kWindowManagerConnection) |
756 return; | 804 return; |
(...skipping 23 matching lines...) Expand all Loading... |
780 client()->OnViewManagerConnectionEstablished( | 828 client()->OnViewManagerConnectionEstablished( |
781 id_, | 829 id_, |
782 creator_url_, | 830 creator_url_, |
783 root_node_manager_->next_server_change_id(), | 831 root_node_manager_->next_server_change_id(), |
784 NodesToNodeDatas(to_send)); | 832 NodesToNodeDatas(to_send)); |
785 } | 833 } |
786 | 834 |
787 } // namespace service | 835 } // namespace service |
788 } // namespace view_manager | 836 } // namespace view_manager |
789 } // namespace mojo | 837 } // namespace mojo |
OLD | NEW |