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_connection.h" | 5 #include "mojo/services/view_manager/view_manager_connection.h" |
6 | 6 |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "mojo/public/cpp/bindings/allocation_scope.h" | 8 #include "mojo/public/cpp/bindings/allocation_scope.h" |
9 #include "mojo/services/view_manager/node.h" | 9 #include "mojo/services/view_manager/node.h" |
10 #include "mojo/services/view_manager/root_node_manager.h" | 10 #include "mojo/services/view_manager/root_node_manager.h" |
(...skipping 29 matching lines...) Expand all Loading... |
40 ViewManagerConnection::~ViewManagerConnection() { | 40 ViewManagerConnection::~ViewManagerConnection() { |
41 // Delete any views we own. | 41 // Delete any views we own. |
42 while (!view_map_.empty()) { | 42 while (!view_map_.empty()) { |
43 bool result = DeleteViewImpl(this, view_map_.begin()->second->id()); | 43 bool result = DeleteViewImpl(this, view_map_.begin()->second->id()); |
44 DCHECK(result); | 44 DCHECK(result); |
45 } | 45 } |
46 | 46 |
47 // We're about to destroy all our nodes. Detach any views from them. | 47 // We're about to destroy all our nodes. Detach any views from them. |
48 for (NodeMap::iterator i = node_map_.begin(); i != node_map_.end(); ++i) { | 48 for (NodeMap::iterator i = node_map_.begin(); i != node_map_.end(); ++i) { |
49 if (i->second->view()) { | 49 if (i->second->view()) { |
50 bool result = SetViewImpl(i->second->id(), ViewId()); | 50 bool result = SetViewImpl(i->second, ViewId()); |
51 DCHECK(result); | 51 DCHECK(result); |
52 } | 52 } |
53 } | 53 } |
54 | 54 |
55 STLDeleteContainerPairSecondPointers(node_map_.begin(), node_map_.end()); | 55 if (!node_map_.empty()) { |
| 56 RootNodeManager::ScopedChange change( |
| 57 this, root_node_manager_, |
| 58 RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true); |
| 59 while (!node_map_.empty()) { |
| 60 Node* node = node_map_.begin()->second; |
| 61 Node* parent = node->GetParent(); |
| 62 const NodeId node_id(node->id()); |
| 63 if (parent) |
| 64 parent->Remove(node); |
| 65 root_node_manager_->ProcessNodeDeleted(node_id); |
| 66 node_map_.erase(NodeIdToTransportId(node_id)); |
| 67 } |
| 68 } |
| 69 |
56 root_node_manager_->RemoveConnection(this); | 70 root_node_manager_->RemoveConnection(this); |
57 } | 71 } |
58 | 72 |
59 void ViewManagerConnection::OnConnectionEstablished() { | 73 void ViewManagerConnection::OnConnectionEstablished() { |
60 DCHECK_EQ(0, id_); // Should only get OnConnectionEstablished() once. | 74 DCHECK_EQ(0, id_); // Should only get OnConnectionEstablished() once. |
61 id_ = root_node_manager_->GetAndAdvanceNextConnectionId(); | 75 id_ = root_node_manager_->GetAndAdvanceNextConnectionId(); |
62 root_node_manager_->AddConnection(this); | 76 root_node_manager_->AddConnection(this); |
63 std::vector<const Node*> to_send; | 77 std::vector<const Node*> to_send; |
64 GetUnknownNodesFrom(root_node_manager_->root(), &to_send); | 78 GetUnknownNodesFrom(root_node_manager_->root(), &to_send); |
65 AllocationScope allocation_scope; | 79 AllocationScope allocation_scope; |
66 client()->OnConnectionEstablished( | 80 client()->OnConnectionEstablished( |
67 id_, | 81 id_, |
68 root_node_manager_->next_server_change_id(), | 82 root_node_manager_->next_server_change_id(), |
69 NodesToINodes(to_send)); | 83 NodesToINodes(to_send)); |
70 } | 84 } |
71 | 85 |
72 const Node* ViewManagerConnection::GetNode(const NodeId& id) const { | 86 const Node* ViewManagerConnection::GetNode(const NodeId& id) const { |
73 if (id_ == id.connection_id) { | 87 if (id_ == id.connection_id) { |
74 NodeMap::const_iterator i = node_map_.find(id.node_id); | 88 NodeMap::const_iterator i = node_map_.find(id.node_id); |
75 return i == node_map_.end() ? NULL : i->second; | 89 return i == node_map_.end() ? NULL : i->second; |
76 } | 90 } |
77 return root_node_manager_->GetNode(id); | 91 return root_node_manager_->GetNode(id); |
78 } | 92 } |
79 | 93 |
80 View* ViewManagerConnection::GetView(const ViewId& id) { | 94 const View* ViewManagerConnection::GetView(const ViewId& id) const { |
81 if (id_ == id.connection_id) { | 95 if (id_ == id.connection_id) { |
82 ViewMap::const_iterator i = view_map_.find(id.view_id); | 96 ViewMap::const_iterator i = view_map_.find(id.view_id); |
83 return i == view_map_.end() ? NULL : i->second; | 97 return i == view_map_.end() ? NULL : i->second; |
84 } | 98 } |
85 return root_node_manager_->GetView(id); | 99 return root_node_manager_->GetView(id); |
86 } | 100 } |
87 | 101 |
88 void ViewManagerConnection::ProcessNodeHierarchyChanged( | 102 void ViewManagerConnection::ProcessNodeHierarchyChanged( |
89 const Node* node, | 103 const Node* node, |
90 const Node* new_parent, | 104 const Node* new_parent, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 ViewIdToTransportId(old_view->id()) : 0; | 156 ViewIdToTransportId(old_view->id()) : 0; |
143 client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()), | 157 client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()), |
144 new_view_id, old_view_id); | 158 new_view_id, old_view_id); |
145 } | 159 } |
146 | 160 |
147 void ViewManagerConnection::ProcessNodeDeleted( | 161 void ViewManagerConnection::ProcessNodeDeleted( |
148 const NodeId& node, | 162 const NodeId& node, |
149 TransportChangeId server_change_id, | 163 TransportChangeId server_change_id, |
150 bool originated_change) { | 164 bool originated_change) { |
151 const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0; | 165 const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0; |
| 166 const bool in_roots = roots_.erase(NodeIdToTransportId(node)) > 0; |
| 167 |
| 168 if (in_roots && roots_.empty()) |
| 169 roots_.insert(NodeIdToTransportId(InvalidNodeId())); |
152 | 170 |
153 if (originated_change) | 171 if (originated_change) |
154 return; | 172 return; |
155 | 173 |
156 if (in_known) { | 174 if (in_known) { |
157 client()->OnNodeDeleted(NodeIdToTransportId(node), server_change_id); | 175 client()->OnNodeDeleted(NodeIdToTransportId(node), server_change_id); |
158 } else if (root_node_manager_->IsProcessingChange()) { | 176 } else if (root_node_manager_->IsProcessingChange()) { |
159 client()->OnServerChangeIdAdvanced( | 177 client()->OnServerChangeIdAdvanced( |
160 root_node_manager_->next_server_change_id() + 1); | 178 root_node_manager_->next_server_change_id() + 1); |
161 } | 179 } |
162 } | 180 } |
163 | 181 |
164 void ViewManagerConnection::ProcessViewDeleted(const ViewId& view, | 182 void ViewManagerConnection::ProcessViewDeleted(const ViewId& view, |
165 bool originated_change) { | 183 bool originated_change) { |
166 if (originated_change) | 184 if (originated_change) |
167 return; | 185 return; |
168 client()->OnViewDeleted(ViewIdToTransportId(view)); | 186 client()->OnViewDeleted(ViewIdToTransportId(view)); |
169 } | 187 } |
170 | 188 |
| 189 bool ViewManagerConnection::CanRemoveNodeFromParent(const Node* node) const { |
| 190 if (!node) |
| 191 return false; |
| 192 |
| 193 const Node* parent = node->GetParent(); |
| 194 if (!parent) |
| 195 return false; |
| 196 |
| 197 // Always allow the remove if there are no roots. Otherwise the remove is |
| 198 // allowed if the parent is a descendant of the roots, or the node and its |
| 199 // parent were created by this connection. We explicitly disallow removal of |
| 200 // the node from its parent if the parent isn't visible to this connection |
| 201 // (not in roots). |
| 202 return (roots_.empty() || |
| 203 (IsNodeDescendantOfRoots(parent) || |
| 204 (node->id().connection_id == id_ && |
| 205 parent->id().connection_id == id_))); |
| 206 } |
| 207 |
| 208 bool ViewManagerConnection::CanAddNode(const Node* parent, |
| 209 const Node* child) const { |
| 210 if (!parent || !child) |
| 211 return false; // Both nodes must be valid. |
| 212 |
| 213 if (child->GetParent() == parent || child->Contains(parent)) |
| 214 return false; // Would result in an invalid hierarchy. |
| 215 |
| 216 if (roots_.empty()) |
| 217 return true; // No restriction if there are no roots. |
| 218 |
| 219 if (!IsNodeDescendantOfRoots(parent) && parent->id().connection_id != id_) |
| 220 return false; // |parent| is not visible to this connection. |
| 221 |
| 222 // Allow the add if the child is already a descendant of the roots or was |
| 223 // created by this connection. |
| 224 return (IsNodeDescendantOfRoots(child) || child->id().connection_id == id_); |
| 225 } |
| 226 |
171 bool ViewManagerConnection::CanDeleteNode(const NodeId& node_id) const { | 227 bool ViewManagerConnection::CanDeleteNode(const NodeId& node_id) const { |
172 return node_id.connection_id == id_; | 228 return node_id.connection_id == id_; |
173 } | 229 } |
174 | 230 |
175 bool ViewManagerConnection::CanDeleteView(const ViewId& view_id) const { | 231 bool ViewManagerConnection::CanDeleteView(const ViewId& view_id) const { |
176 return view_id.connection_id == id_; | 232 return view_id.connection_id == id_; |
177 } | 233 } |
178 | 234 |
| 235 bool ViewManagerConnection::CanSetView(const Node* node, |
| 236 const ViewId& view_id) const { |
| 237 if (!node || !IsNodeDescendantOfRoots(node)) |
| 238 return false; |
| 239 |
| 240 const View* view = GetView(view_id); |
| 241 return (view && view_id.connection_id == id_) || view_id == ViewId(); |
| 242 } |
| 243 |
| 244 bool ViewManagerConnection::CanGetNodeTree(const Node* node) const { |
| 245 return node && |
| 246 (IsNodeDescendantOfRoots(node) || node->id().connection_id == id_); |
| 247 } |
| 248 |
179 bool ViewManagerConnection::DeleteNodeImpl(ViewManagerConnection* source, | 249 bool ViewManagerConnection::DeleteNodeImpl(ViewManagerConnection* source, |
180 const NodeId& node_id) { | 250 const NodeId& node_id) { |
181 DCHECK_EQ(node_id.connection_id, id_); | 251 DCHECK_EQ(node_id.connection_id, id_); |
182 Node* node = GetNode(node_id); | 252 Node* node = GetNode(node_id); |
183 if (!node) | 253 if (!node) |
184 return false; | 254 return false; |
185 RootNodeManager::ScopedChange change( | 255 RootNodeManager::ScopedChange change( |
186 source, root_node_manager_, | 256 source, root_node_manager_, |
187 RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true); | 257 RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true); |
188 if (node->GetParent()) | 258 if (node->GetParent()) |
(...skipping 22 matching lines...) Expand all Loading... |
211 view->node()->SetView(NULL); | 281 view->node()->SetView(NULL); |
212 view_map_.erase(view_id.view_id); | 282 view_map_.erase(view_id.view_id); |
213 // Make a copy of |view_id| as once we delete view |view_id| may no longer be | 283 // Make a copy of |view_id| as once we delete view |view_id| may no longer be |
214 // valid. | 284 // valid. |
215 const ViewId view_id_copy(view_id); | 285 const ViewId view_id_copy(view_id); |
216 delete view; | 286 delete view; |
217 root_node_manager_->ProcessViewDeleted(view_id_copy); | 287 root_node_manager_->ProcessViewDeleted(view_id_copy); |
218 return true; | 288 return true; |
219 } | 289 } |
220 | 290 |
221 bool ViewManagerConnection::SetViewImpl(const NodeId& node_id, | 291 bool ViewManagerConnection::SetViewImpl(Node* node, const ViewId& view_id) { |
222 const ViewId& view_id) { | 292 DCHECK(node); // CanSetView() should have verified node exists. |
223 Node* node = GetNode(node_id); | |
224 if (!node) | |
225 return false; | |
226 View* view = GetView(view_id); | 293 View* view = GetView(view_id); |
227 if (!view && view_id != ViewId()) | |
228 return false; | |
229 RootNodeManager::ScopedChange change( | 294 RootNodeManager::ScopedChange change( |
230 this, root_node_manager_, | 295 this, root_node_manager_, |
231 RootNodeManager::CHANGE_TYPE_DONT_ADVANCE_SERVER_CHANGE_ID, false); | 296 RootNodeManager::CHANGE_TYPE_DONT_ADVANCE_SERVER_CHANGE_ID, false); |
232 node->SetView(view); | 297 node->SetView(view); |
233 return true; | 298 return true; |
234 } | 299 } |
235 | 300 |
236 void ViewManagerConnection::GetUnknownNodesFrom( | 301 void ViewManagerConnection::GetUnknownNodesFrom( |
237 const Node* node, | 302 const Node* node, |
238 std::vector<const Node*>* nodes) { | 303 std::vector<const Node*>* nodes) { |
(...skipping 14 matching lines...) Expand all Loading... |
253 std::vector<const Node*> children = node->GetChildren(); | 318 std::vector<const Node*> children = node->GetChildren(); |
254 for (size_t i = 0; i < children.size(); ++i) | 319 for (size_t i = 0; i < children.size(); ++i) |
255 RemoveFromKnown(children[i]); | 320 RemoveFromKnown(children[i]); |
256 } | 321 } |
257 | 322 |
258 bool ViewManagerConnection::IsNodeDescendantOfRoots(const Node* node) const { | 323 bool ViewManagerConnection::IsNodeDescendantOfRoots(const Node* node) const { |
259 if (roots_.empty()) | 324 if (roots_.empty()) |
260 return true; | 325 return true; |
261 if (!node) | 326 if (!node) |
262 return false; | 327 return false; |
| 328 const TransportNodeId invalid_node_id = |
| 329 NodeIdToTransportId(InvalidNodeId()); |
263 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) { | 330 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) { |
| 331 if (*i == invalid_node_id) |
| 332 continue; |
264 const Node* root = GetNode(NodeIdFromTransportId(*i)); | 333 const Node* root = GetNode(NodeIdFromTransportId(*i)); |
265 DCHECK(root); | 334 DCHECK(root); |
266 if (root->Contains(node)) | 335 if (root->Contains(node)) |
267 return true; | 336 return true; |
268 } | 337 } |
269 return false; | 338 return false; |
270 } | 339 } |
271 | 340 |
272 bool ViewManagerConnection::ShouldNotifyOnHierarchyChange( | 341 bool ViewManagerConnection::ShouldNotifyOnHierarchyChange( |
273 const Node* node, | 342 const Node* node, |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 | 469 |
401 void ViewManagerConnection::AddNode( | 470 void ViewManagerConnection::AddNode( |
402 TransportNodeId parent_id, | 471 TransportNodeId parent_id, |
403 TransportNodeId child_id, | 472 TransportNodeId child_id, |
404 TransportChangeId server_change_id, | 473 TransportChangeId server_change_id, |
405 const Callback<void(bool)>& callback) { | 474 const Callback<void(bool)>& callback) { |
406 bool success = false; | 475 bool success = false; |
407 if (server_change_id == root_node_manager_->next_server_change_id()) { | 476 if (server_change_id == root_node_manager_->next_server_change_id()) { |
408 Node* parent = GetNode(NodeIdFromTransportId(parent_id)); | 477 Node* parent = GetNode(NodeIdFromTransportId(parent_id)); |
409 Node* child = GetNode(NodeIdFromTransportId(child_id)); | 478 Node* child = GetNode(NodeIdFromTransportId(child_id)); |
410 if (parent && child && child->GetParent() != parent && | 479 if (CanAddNode(parent, child)) { |
411 !child->window()->Contains(parent->window())) { | |
412 success = true; | 480 success = true; |
413 RootNodeManager::ScopedChange change( | 481 RootNodeManager::ScopedChange change( |
414 this, root_node_manager_, | 482 this, root_node_manager_, |
415 RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, false); | 483 RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, false); |
416 parent->Add(child); | 484 parent->Add(child); |
417 } | 485 } |
418 } | 486 } |
419 callback.Run(success); | 487 callback.Run(success); |
420 } | 488 } |
421 | 489 |
422 void ViewManagerConnection::RemoveNodeFromParent( | 490 void ViewManagerConnection::RemoveNodeFromParent( |
423 TransportNodeId node_id, | 491 TransportNodeId node_id, |
424 TransportChangeId server_change_id, | 492 TransportChangeId server_change_id, |
425 const Callback<void(bool)>& callback) { | 493 const Callback<void(bool)>& callback) { |
426 bool success = false; | 494 bool success = false; |
427 if (server_change_id == root_node_manager_->next_server_change_id()) { | 495 if (server_change_id == root_node_manager_->next_server_change_id()) { |
428 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 496 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
429 if (node && node->GetParent()) { | 497 if (CanRemoveNodeFromParent(node)) { |
430 success = true; | 498 success = true; |
431 RootNodeManager::ScopedChange change( | 499 RootNodeManager::ScopedChange change( |
432 this, root_node_manager_, | 500 this, root_node_manager_, |
433 RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, false); | 501 RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, false); |
434 node->GetParent()->Remove(node); | 502 node->GetParent()->Remove(node); |
435 } | 503 } |
436 } | 504 } |
437 callback.Run(success); | 505 callback.Run(success); |
438 } | 506 } |
439 | 507 |
440 void ViewManagerConnection::GetNodeTree( | 508 void ViewManagerConnection::GetNodeTree( |
441 TransportNodeId node_id, | 509 TransportNodeId node_id, |
442 const Callback<void(Array<INode>)>& callback) { | 510 const Callback<void(Array<INode>)>& callback) { |
443 AllocationScope allocation_scope; | 511 AllocationScope allocation_scope; |
444 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 512 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
445 std::vector<const Node*> nodes; | 513 std::vector<const Node*> nodes; |
446 GetDescendants(node, &nodes); | 514 if (CanGetNodeTree(node)) { |
447 for (size_t i = 0; i < nodes.size(); ++i) | 515 GetDescendants(node, &nodes); |
448 known_nodes_.insert(NodeIdToTransportId(nodes[i]->id())); | 516 for (size_t i = 0; i < nodes.size(); ++i) |
| 517 known_nodes_.insert(NodeIdToTransportId(nodes[i]->id())); |
| 518 } |
449 callback.Run(NodesToINodes(nodes)); | 519 callback.Run(NodesToINodes(nodes)); |
450 } | 520 } |
451 | 521 |
452 void ViewManagerConnection::CreateView( | 522 void ViewManagerConnection::CreateView( |
453 TransportViewId transport_view_id, | 523 TransportViewId transport_view_id, |
454 const Callback<void(bool)>& callback) { | 524 const Callback<void(bool)>& callback) { |
455 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); | 525 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); |
456 if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) { | 526 if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) { |
457 callback.Run(false); | 527 callback.Run(false); |
458 return; | 528 return; |
(...skipping 12 matching lines...) Expand all Loading... |
471 view_id.connection_id); | 541 view_id.connection_id); |
472 did_delete = (connection && connection->DeleteViewImpl(this, view_id)); | 542 did_delete = (connection && connection->DeleteViewImpl(this, view_id)); |
473 } | 543 } |
474 callback.Run(did_delete); | 544 callback.Run(did_delete); |
475 } | 545 } |
476 | 546 |
477 void ViewManagerConnection::SetView( | 547 void ViewManagerConnection::SetView( |
478 TransportNodeId transport_node_id, | 548 TransportNodeId transport_node_id, |
479 TransportViewId transport_view_id, | 549 TransportViewId transport_view_id, |
480 const Callback<void(bool)>& callback) { | 550 const Callback<void(bool)>& callback) { |
481 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | 551 Node* node = GetNode(NodeIdFromTransportId(transport_node_id)); |
482 callback.Run(SetViewImpl(node_id, ViewIdFromTransportId(transport_view_id))); | 552 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); |
| 553 callback.Run(CanSetView(node, view_id) && SetViewImpl(node, view_id)); |
483 } | 554 } |
484 | 555 |
485 void ViewManagerConnection::SetViewContents( | 556 void ViewManagerConnection::SetViewContents( |
486 TransportViewId view_id, | 557 TransportViewId view_id, |
487 ScopedSharedBufferHandle buffer, | 558 ScopedSharedBufferHandle buffer, |
488 uint32_t buffer_size) { | 559 uint32_t buffer_size) { |
489 View* view = GetView(ViewIdFromTransportId(view_id)); | 560 View* view = GetView(ViewIdFromTransportId(view_id)); |
490 if (!view) | 561 if (!view) |
491 return; | 562 return; |
492 void* handle_data; | 563 void* handle_data; |
(...skipping 26 matching lines...) Expand all Loading... |
519 | 590 |
520 void ViewManagerConnection::OnNodeViewReplaced(const Node* node, | 591 void ViewManagerConnection::OnNodeViewReplaced(const Node* node, |
521 const View* new_view, | 592 const View* new_view, |
522 const View* old_view) { | 593 const View* old_view) { |
523 root_node_manager_->ProcessNodeViewReplaced(node, new_view, old_view); | 594 root_node_manager_->ProcessNodeViewReplaced(node, new_view, old_view); |
524 } | 595 } |
525 | 596 |
526 } // namespace service | 597 } // namespace service |
527 } // namespace view_manager | 598 } // namespace view_manager |
528 } // namespace mojo | 599 } // namespace mojo |
OLD | NEW |