Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(111)

Side by Side Diff: mojo/services/view_manager/view_manager_connection.cc

Issue 296003003: First step at setroots (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comment Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
OLDNEW
« no previous file with comments | « mojo/services/view_manager/view_manager_connection.h ('k') | mojo/services/view_manager/view_manager_connection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698