| 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 |