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" |
11 #include "mojo/services/view_manager/type_converters.h" | |
12 #include "mojo/services/view_manager/view.h" | 11 #include "mojo/services/view_manager/view.h" |
13 #include "third_party/skia/include/core/SkBitmap.h" | 12 #include "third_party/skia/include/core/SkBitmap.h" |
14 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
15 #include "ui/gfx/codec/png_codec.h" | 14 #include "ui/gfx/codec/png_codec.h" |
16 | 15 |
17 namespace mojo { | 16 namespace mojo { |
18 namespace view_manager { | 17 namespace view_manager { |
19 namespace service { | 18 namespace service { |
20 namespace { | 19 namespace { |
21 | 20 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 void ViewManagerConnection::OnConnectionEstablished() { | 59 void ViewManagerConnection::OnConnectionEstablished() { |
61 DCHECK_EQ(0, id_); // Should only get OnConnectionEstablished() once. | 60 DCHECK_EQ(0, id_); // Should only get OnConnectionEstablished() once. |
62 id_ = root_node_manager_->GetAndAdvanceNextConnectionId(); | 61 id_ = root_node_manager_->GetAndAdvanceNextConnectionId(); |
63 root_node_manager_->AddConnection(this); | 62 root_node_manager_->AddConnection(this); |
64 std::vector<const Node*> to_send; | 63 std::vector<const Node*> to_send; |
65 GetUnknownNodesFrom(root_node_manager_->root(), &to_send); | 64 GetUnknownNodesFrom(root_node_manager_->root(), &to_send); |
66 AllocationScope allocation_scope; | 65 AllocationScope allocation_scope; |
67 client()->OnConnectionEstablished( | 66 client()->OnConnectionEstablished( |
68 id_, | 67 id_, |
69 root_node_manager_->next_server_change_id(), | 68 root_node_manager_->next_server_change_id(), |
70 Array<INode>::From(to_send)); | 69 NodesToINodes(to_send)); |
71 } | 70 } |
72 | 71 |
73 const Node* ViewManagerConnection::GetNode(const NodeId& id) const { | 72 const Node* ViewManagerConnection::GetNode(const NodeId& id) const { |
74 if (id_ == id.connection_id) { | 73 if (id_ == id.connection_id) { |
75 NodeMap::const_iterator i = node_map_.find(id.node_id); | 74 NodeMap::const_iterator i = node_map_.find(id.node_id); |
76 return i == node_map_.end() ? NULL : i->second; | 75 return i == node_map_.end() ? NULL : i->second; |
77 } | 76 } |
78 return root_node_manager_->GetNode(id); | 77 return root_node_manager_->GetNode(id); |
79 } | 78 } |
80 | 79 |
81 View* ViewManagerConnection::GetView(const ViewId& id) { | 80 View* ViewManagerConnection::GetView(const ViewId& id) { |
82 if (id_ == id.connection_id) { | 81 if (id_ == id.connection_id) { |
83 ViewMap::const_iterator i = view_map_.find(id.view_id); | 82 ViewMap::const_iterator i = view_map_.find(id.view_id); |
84 return i == view_map_.end() ? NULL : i->second; | 83 return i == view_map_.end() ? NULL : i->second; |
85 } | 84 } |
86 return root_node_manager_->GetView(id); | 85 return root_node_manager_->GetView(id); |
87 } | 86 } |
88 | 87 |
89 void ViewManagerConnection::ProcessNodeHierarchyChanged( | 88 void ViewManagerConnection::ProcessNodeHierarchyChanged( |
90 const Node* node, | 89 const Node* node, |
91 const Node* new_parent, | 90 const Node* new_parent, |
92 const Node* old_parent, | 91 const Node* old_parent, |
93 TransportChangeId server_change_id, | 92 TransportChangeId server_change_id, |
94 bool originated_change) { | 93 bool originated_change) { |
| 94 if (known_nodes_.count(NodeIdToTransportId(node->id())) > 0) { |
| 95 if (originated_change) |
| 96 return; |
| 97 if (node->id().connection_id != id_ && !IsNodeDescendantOfRoots(node)) { |
| 98 // Node was a descendant of roots and is no longer, treat it as though the |
| 99 // node was deleted. |
| 100 RemoveFromKnown(node); |
| 101 client()->OnNodeDeleted(NodeIdToTransportId(node->id()), |
| 102 server_change_id); |
| 103 return; |
| 104 } |
| 105 } |
| 106 |
95 if (originated_change || root_node_manager_->is_processing_delete_node()) | 107 if (originated_change || root_node_manager_->is_processing_delete_node()) |
96 return; | 108 return; |
97 std::vector<const Node*> to_send; | 109 std::vector<const Node*> to_send; |
98 if (!ShouldNotifyOnHierarchyChange(node, new_parent, old_parent, &to_send)) { | 110 if (!ShouldNotifyOnHierarchyChange(node, &new_parent, &old_parent, |
| 111 &to_send)) { |
99 if (root_node_manager_->IsProcessingChange()) { | 112 if (root_node_manager_->IsProcessingChange()) { |
100 client()->OnServerChangeIdAdvanced( | 113 client()->OnServerChangeIdAdvanced( |
101 root_node_manager_->next_server_change_id() + 1); | 114 root_node_manager_->next_server_change_id() + 1); |
102 } | 115 } |
103 return; | 116 return; |
104 } | 117 } |
105 AllocationScope allocation_scope; | 118 AllocationScope allocation_scope; |
106 const NodeId new_parent_id(new_parent ? new_parent->id() : NodeId()); | 119 const NodeId new_parent_id(new_parent ? new_parent->id() : NodeId()); |
107 const NodeId old_parent_id(old_parent ? old_parent->id() : NodeId()); | 120 const NodeId old_parent_id(old_parent ? old_parent->id() : NodeId()); |
| 121 DCHECK((node->id().connection_id == id_) || |
| 122 (roots_.count(NodeIdToTransportId(node->id())) > 0) || |
| 123 (new_parent && IsNodeDescendantOfRoots(new_parent)) || |
| 124 (old_parent && IsNodeDescendantOfRoots(old_parent))); |
108 client()->OnNodeHierarchyChanged(NodeIdToTransportId(node->id()), | 125 client()->OnNodeHierarchyChanged(NodeIdToTransportId(node->id()), |
109 NodeIdToTransportId(new_parent_id), | 126 NodeIdToTransportId(new_parent_id), |
110 NodeIdToTransportId(old_parent_id), | 127 NodeIdToTransportId(old_parent_id), |
111 server_change_id, | 128 server_change_id, |
112 Array<INode>::From(to_send)); | 129 NodesToINodes(to_send)); |
113 } | 130 } |
114 | 131 |
115 void ViewManagerConnection::ProcessNodeViewReplaced( | 132 void ViewManagerConnection::ProcessNodeViewReplaced( |
116 const Node* node, | 133 const Node* node, |
117 const View* new_view, | 134 const View* new_view, |
118 const View* old_view, | 135 const View* old_view, |
119 bool originated_change) { | 136 bool originated_change) { |
120 if (originated_change) | 137 if (originated_change || !known_nodes_.count(NodeIdToTransportId(node->id()))) |
121 return; | 138 return; |
122 if (known_nodes_.count(NodeIdToTransportId(node->id())) > 0) { | 139 const TransportViewId new_view_id = new_view ? |
123 const TransportViewId new_view_id = new_view ? | 140 ViewIdToTransportId(new_view->id()) : 0; |
124 ViewIdToTransportId(new_view->id()) : 0; | 141 const TransportViewId old_view_id = old_view ? |
125 const TransportViewId old_view_id = old_view ? | 142 ViewIdToTransportId(old_view->id()) : 0; |
126 ViewIdToTransportId(old_view->id()) : 0; | 143 client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()), |
127 client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()), | 144 new_view_id, old_view_id); |
128 new_view_id, old_view_id); | |
129 } | |
130 } | 145 } |
131 | 146 |
132 void ViewManagerConnection::ProcessNodeDeleted( | 147 void ViewManagerConnection::ProcessNodeDeleted( |
133 const NodeId& node, | 148 const NodeId& node, |
134 TransportChangeId server_change_id, | 149 TransportChangeId server_change_id, |
135 bool originated_change) { | 150 bool originated_change) { |
136 const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0; | 151 const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0; |
137 | 152 |
138 if (originated_change) | 153 if (originated_change) |
139 return; | 154 return; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 const TransportNodeId transport_id = NodeIdToTransportId(node->id()); | 239 const TransportNodeId transport_id = NodeIdToTransportId(node->id()); |
225 if (known_nodes_.count(transport_id) == 1) | 240 if (known_nodes_.count(transport_id) == 1) |
226 return; | 241 return; |
227 nodes->push_back(node); | 242 nodes->push_back(node); |
228 known_nodes_.insert(transport_id); | 243 known_nodes_.insert(transport_id); |
229 std::vector<const Node*> children(node->GetChildren()); | 244 std::vector<const Node*> children(node->GetChildren()); |
230 for (size_t i = 0 ; i < children.size(); ++i) | 245 for (size_t i = 0 ; i < children.size(); ++i) |
231 GetUnknownNodesFrom(children[i], nodes); | 246 GetUnknownNodesFrom(children[i], nodes); |
232 } | 247 } |
233 | 248 |
| 249 void ViewManagerConnection::RemoveFromKnown(const Node* node) { |
| 250 if (node->id().connection_id == id_) |
| 251 return; |
| 252 known_nodes_.erase(NodeIdToTransportId(node->id())); |
| 253 std::vector<const Node*> children = node->GetChildren(); |
| 254 for (size_t i = 0; i < children.size(); ++i) |
| 255 RemoveFromKnown(children[i]); |
| 256 } |
| 257 |
| 258 bool ViewManagerConnection::IsNodeDescendantOfRoots(const Node* node) const { |
| 259 if (roots_.empty()) |
| 260 return true; |
| 261 if (!node) |
| 262 return false; |
| 263 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) { |
| 264 const Node* root = GetNode(NodeIdFromTransportId(*i)); |
| 265 DCHECK(root); |
| 266 if (root->Contains(node)) |
| 267 return true; |
| 268 } |
| 269 return false; |
| 270 } |
| 271 |
234 bool ViewManagerConnection::ShouldNotifyOnHierarchyChange( | 272 bool ViewManagerConnection::ShouldNotifyOnHierarchyChange( |
235 const Node* node, | 273 const Node* node, |
236 const Node* new_parent, | 274 const Node** new_parent, |
237 const Node* old_parent, | 275 const Node** old_parent, |
238 std::vector<const Node*>* to_send) { | 276 std::vector<const Node*>* to_send) { |
239 if (new_parent) { | 277 // If the node is not in |roots_| or was never known to this connection then |
| 278 // don't notify the client about it. |
| 279 if (node->id().connection_id != id_ && |
| 280 known_nodes_.count(NodeIdToTransportId(node->id())) == 0 && |
| 281 !IsNodeDescendantOfRoots(node)) { |
| 282 return false; |
| 283 } |
| 284 if (!IsNodeDescendantOfRoots(*new_parent)) |
| 285 *new_parent = NULL; |
| 286 if (!IsNodeDescendantOfRoots(*old_parent)) |
| 287 *old_parent = NULL; |
| 288 |
| 289 if (*new_parent) { |
240 // On getting a new parent we may need to communicate new nodes to the | 290 // On getting a new parent we may need to communicate new nodes to the |
241 // client. We do that in the following cases: | 291 // client. We do that in the following cases: |
242 // . New parent is a descendant of the root. In this case the client already | 292 // . New parent is a descendant of the roots. In this case the client |
243 // knows all ancestors, so we only have to communicate descendants of node | 293 // already knows all ancestors, so we only have to communicate descendants |
244 // the client doesn't know about. | 294 // of node the client doesn't know about. |
245 // . If the client knew about the parent, we have to do the same. | 295 // . If the client knew about the parent, we have to do the same. |
246 // . If the client knows about the node and is added to a tree the client | 296 // . If the client knows about the node and is added to a tree the client |
247 // doesn't know about we have to communicate from the root down (the | 297 // doesn't know about we have to communicate from the root down (the |
248 // client is learning about a new root). | 298 // client is learning about a new root). |
249 if (root_node_manager_->root()->Contains(new_parent) || | 299 if (root_node_manager_->root()->Contains(*new_parent) || |
250 known_nodes_.count(NodeIdToTransportId(new_parent->id()))) { | 300 known_nodes_.count(NodeIdToTransportId((*new_parent)->id()))) { |
251 GetUnknownNodesFrom(node, to_send); | 301 GetUnknownNodesFrom(node, to_send); |
252 return true; | 302 return true; |
253 } | 303 } |
254 // If parent wasn't known we have to communicate from the root down. | 304 // If parent wasn't known we have to communicate from the root down. |
255 if (known_nodes_.count(NodeIdToTransportId(node->id()))) { | 305 if (known_nodes_.count(NodeIdToTransportId(node->id()))) { |
256 GetUnknownNodesFrom(new_parent->GetRoot(), to_send); | 306 // No need to check against |roots_| as client should always know it's |
| 307 // |roots_|. |
| 308 GetUnknownNodesFrom((*new_parent)->GetRoot(), to_send); |
257 return true; | 309 return true; |
258 } | 310 } |
259 } | 311 } |
260 // Otherwise only communicate the change if the node was known. We shouldn't | 312 // Otherwise only communicate the change if the node was known. We shouldn't |
261 // need to communicate any nodes on a remove. | 313 // need to communicate any nodes on a remove. |
262 return known_nodes_.count(NodeIdToTransportId(node->id())) > 0; | 314 return known_nodes_.count(NodeIdToTransportId(node->id())) > 0; |
263 } | 315 } |
264 | 316 |
| 317 bool ViewManagerConnection::ProcessSetRoots( |
| 318 TransportConnectionId source_connection_id, |
| 319 const Array<TransportNodeId>& transport_node_ids) { |
| 320 // TODO(sky): these DCHECKs can go away once this is part of a real API. Also |
| 321 // make sure that when roots are set nodes are communicate to client. Code in |
| 322 // ProcessNodeHierarchyChanged() is depending on this. |
| 323 DCHECK(node_map_.empty()); |
| 324 DCHECK(view_map_.empty()); |
| 325 |
| 326 NodeIdSet roots; |
| 327 for (size_t i = 0; i < transport_node_ids.size(); ++i) { |
| 328 const Node* node = GetNode(NodeIdFromTransportId(transport_node_ids[i])); |
| 329 // Only allow setting roots that are owned by the source connection. |
| 330 if (!node || node->id().connection_id != source_connection_id) |
| 331 return false; |
| 332 roots.insert(transport_node_ids[i]); |
| 333 } |
| 334 roots_.swap(roots); |
| 335 |
| 336 // TODO(sky): remove |known_nodes_.clear()| temporary while this is done here |
| 337 // instead of at creation time. |
| 338 known_nodes_.clear(); |
| 339 std::vector<const Node*> to_send; |
| 340 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) |
| 341 GetUnknownNodesFrom(GetNode(NodeIdFromTransportId(*i)), &to_send); |
| 342 AllocationScope allocation_scope; |
| 343 client()->OnConnectionEstablished( |
| 344 id_, |
| 345 root_node_manager_->next_server_change_id(), |
| 346 NodesToINodes(to_send)); |
| 347 |
| 348 return true; |
| 349 } |
| 350 |
| 351 Array<INode> ViewManagerConnection::NodesToINodes( |
| 352 const std::vector<const Node*>& nodes) { |
| 353 Array<INode>::Builder array_builder(nodes.size()); |
| 354 for (size_t i = 0; i < nodes.size(); ++i) { |
| 355 INode::Builder node_builder; |
| 356 const Node* node = nodes[i]; |
| 357 DCHECK(known_nodes_.count(NodeIdToTransportId(node->id())) > 0); |
| 358 const Node* parent = node->GetParent(); |
| 359 // If the parent isn't known, it means the parent is not visible to us (not |
| 360 // in roots), and should not be sent over. |
| 361 if (parent && known_nodes_.count(NodeIdToTransportId(parent->id())) == 0) |
| 362 parent = NULL; |
| 363 node_builder.set_parent_id(NodeIdToTransportId( |
| 364 parent ? parent->id() : NodeId())); |
| 365 node_builder.set_node_id(NodeIdToTransportId(node->id())); |
| 366 node_builder.set_view_id(ViewIdToTransportId( |
| 367 node->view() ? node->view()->id() : ViewId())); |
| 368 array_builder[i] = node_builder.Finish(); |
| 369 } |
| 370 return array_builder.Finish(); |
| 371 } |
| 372 |
265 void ViewManagerConnection::CreateNode( | 373 void ViewManagerConnection::CreateNode( |
266 TransportNodeId transport_node_id, | 374 TransportNodeId transport_node_id, |
267 const Callback<void(bool)>& callback) { | 375 const Callback<void(bool)>& callback) { |
268 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | 376 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); |
269 if (node_id.connection_id != id_ || | 377 if (node_id.connection_id != id_ || |
270 node_map_.find(node_id.node_id) != node_map_.end()) { | 378 node_map_.find(node_id.node_id) != node_map_.end()) { |
271 callback.Run(false); | 379 callback.Run(false); |
272 return; | 380 return; |
273 } | 381 } |
274 node_map_[node_id.node_id] = new Node(this, node_id); | 382 node_map_[node_id.node_id] = new Node(this, node_id); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
331 | 439 |
332 void ViewManagerConnection::GetNodeTree( | 440 void ViewManagerConnection::GetNodeTree( |
333 TransportNodeId node_id, | 441 TransportNodeId node_id, |
334 const Callback<void(Array<INode>)>& callback) { | 442 const Callback<void(Array<INode>)>& callback) { |
335 AllocationScope allocation_scope; | 443 AllocationScope allocation_scope; |
336 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 444 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
337 std::vector<const Node*> nodes; | 445 std::vector<const Node*> nodes; |
338 GetDescendants(node, &nodes); | 446 GetDescendants(node, &nodes); |
339 for (size_t i = 0; i < nodes.size(); ++i) | 447 for (size_t i = 0; i < nodes.size(); ++i) |
340 known_nodes_.insert(NodeIdToTransportId(nodes[i]->id())); | 448 known_nodes_.insert(NodeIdToTransportId(nodes[i]->id())); |
341 callback.Run(Array<INode>::From(nodes)); | 449 callback.Run(NodesToINodes(nodes)); |
342 } | 450 } |
343 | 451 |
344 void ViewManagerConnection::CreateView( | 452 void ViewManagerConnection::CreateView( |
345 TransportViewId transport_view_id, | 453 TransportViewId transport_view_id, |
346 const Callback<void(bool)>& callback) { | 454 const Callback<void(bool)>& callback) { |
347 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); | 455 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); |
348 if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) { | 456 if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) { |
349 callback.Run(false); | 457 callback.Run(false); |
350 return; | 458 return; |
351 } | 459 } |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 MOJO_MAP_BUFFER_FLAG_NONE) != MOJO_RESULT_OK) { | 494 MOJO_MAP_BUFFER_FLAG_NONE) != MOJO_RESULT_OK) { |
387 return; | 495 return; |
388 } | 496 } |
389 SkBitmap bitmap; | 497 SkBitmap bitmap; |
390 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(handle_data), | 498 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(handle_data), |
391 buffer_size, &bitmap); | 499 buffer_size, &bitmap); |
392 view->SetBitmap(bitmap); | 500 view->SetBitmap(bitmap); |
393 UnmapBuffer(handle_data); | 501 UnmapBuffer(handle_data); |
394 } | 502 } |
395 | 503 |
| 504 void ViewManagerConnection::SetRoots( |
| 505 TransportConnectionId connection_id, |
| 506 const Array<TransportNodeId>& transport_node_ids, |
| 507 const Callback<void(bool)>& callback) { |
| 508 ViewManagerConnection* connection = |
| 509 root_node_manager_->GetConnection(connection_id); |
| 510 callback.Run(connection && |
| 511 connection->ProcessSetRoots(id_, transport_node_ids)); |
| 512 } |
| 513 |
396 void ViewManagerConnection::OnNodeHierarchyChanged(const Node* node, | 514 void ViewManagerConnection::OnNodeHierarchyChanged(const Node* node, |
397 const Node* new_parent, | 515 const Node* new_parent, |
398 const Node* old_parent) { | 516 const Node* old_parent) { |
399 root_node_manager_->ProcessNodeHierarchyChanged(node, new_parent, old_parent); | 517 root_node_manager_->ProcessNodeHierarchyChanged(node, new_parent, old_parent); |
400 } | 518 } |
401 | 519 |
402 void ViewManagerConnection::OnNodeViewReplaced(const Node* node, | 520 void ViewManagerConnection::OnNodeViewReplaced(const Node* node, |
403 const View* new_view, | 521 const View* new_view, |
404 const View* old_view) { | 522 const View* old_view) { |
405 root_node_manager_->ProcessNodeViewReplaced(node, new_view, old_view); | 523 root_node_manager_->ProcessNodeViewReplaced(node, new_view, old_view); |
406 } | 524 } |
407 | 525 |
408 } // namespace service | 526 } // namespace service |
409 } // namespace view_manager | 527 } // namespace view_manager |
410 } // namespace mojo | 528 } // namespace mojo |
OLD | NEW |