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

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

Issue 415793003: Changes access policy for embedded nodes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: cleanup Created 6 years, 5 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_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"
11 #include "mojo/services/view_manager/root_node_manager.h" 11 #include "mojo/services/view_manager/root_node_manager.h"
12 #include "mojo/services/view_manager/view.h" 12 #include "mojo/services/view_manager/view.h"
13 #include "third_party/skia/include/core/SkBitmap.h" 13 #include "third_party/skia/include/core/SkBitmap.h"
14 #include "ui/aura/window.h" 14 #include "ui/aura/window.h"
15 #include "ui/gfx/codec/png_codec.h" 15 #include "ui/gfx/codec/png_codec.h"
16 16
17 namespace mojo { 17 namespace mojo {
18 namespace view_manager { 18 namespace view_manager {
19 namespace service { 19 namespace service {
20 namespace {
21
22 // Places |node| in |nodes| and recurses through the children.
23 void GetDescendants(const Node* node, std::vector<const Node*>* nodes) {
24 if (!node)
25 return;
26
27 nodes->push_back(node);
28
29 std::vector<const Node*> children(node->GetChildren());
30 for (size_t i = 0 ; i < children.size(); ++i)
31 GetDescendants(children[i], nodes);
32 }
33
34 } // namespace
35 20
36 ViewManagerServiceImpl::ViewManagerServiceImpl( 21 ViewManagerServiceImpl::ViewManagerServiceImpl(
37 RootNodeManager* root_node_manager, 22 RootNodeManager* root_node_manager,
38 ConnectionSpecificId creator_id, 23 ConnectionSpecificId creator_id,
39 const std::string& creator_url, 24 const std::string& creator_url,
40 const std::string& url, 25 const std::string& url,
41 const NodeId& root_id) 26 const NodeId& root_id)
42 : root_node_manager_(root_node_manager), 27 : root_node_manager_(root_node_manager),
43 id_(root_node_manager_->GetAndAdvanceNextConnectionId()), 28 id_(root_node_manager_->GetAndAdvanceNextConnectionId()),
44 url_(url), 29 url_(url),
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 219 }
235 220
236 bool ViewManagerServiceImpl::CanRemoveNodeFromParent(const Node* node) const { 221 bool ViewManagerServiceImpl::CanRemoveNodeFromParent(const Node* node) const {
237 if (!node) 222 if (!node)
238 return false; 223 return false;
239 224
240 const Node* parent = node->GetParent(); 225 const Node* parent = node->GetParent();
241 if (!parent) 226 if (!parent)
242 return false; 227 return false;
243 228
244 // Always allow the remove if there are no roots. Otherwise the remove is 229 if (roots_.empty())
245 // allowed if the parent is a descendant of the roots, or the node and its 230 return true; // Root can do anything.
246 // parent were created by this connection. We explicitly disallow removal of 231
247 // the node from its parent if the parent isn't visible to this connection 232 if (node->id().connection_id != id_)
248 // (not in roots). 233 return false; // Can only unparent nodes we created.
249 return (roots_.empty() || 234
250 (IsNodeDescendantOfRoots(parent) || 235 if (roots_.count(NodeIdToTransportId(parent->id())) > 0)
251 (node->id().connection_id == id_ && 236 return true; // We can always remove from one of our roots.
252 parent->id().connection_id == id_))); 237
238 // Don't allow removing from nodes from other connections that aren't in our
239 // root list.
240 if (parent->id().connection_id != id_)
241 return false;
242
243 // Allow the remove as long as we haven't embedded another node at |parent|.
244 ViewManagerServiceImpl* connection =
245 root_node_manager_->GetConnectionWithRoot(parent->id());
246 return !connection || connection == this;
253 } 247 }
254 248
255 bool ViewManagerServiceImpl::CanAddNode(const Node* parent, 249 bool ViewManagerServiceImpl::CanAddNode(const Node* parent,
256 const Node* child) const { 250 const Node* child) const {
257 if (!parent || !child) 251 if (!parent || !child)
258 return false; // Both nodes must be valid. 252 return false; // Both nodes must be valid.
259 253
260 if (child->GetParent() == parent || child->Contains(parent)) 254 if (child->GetParent() == parent || child->Contains(parent))
261 return false; // Would result in an invalid hierarchy. 255 return false; // Would result in an invalid hierarchy.
262 256
263 if (roots_.empty()) 257 if (roots_.empty())
264 return true; // No restriction if there are no roots. 258 return true; // No restriction if there are no roots.
265 259
260 if (child->id().connection_id != id_)
261 return false; // Can't move children from different connections.
262
266 if (!IsNodeDescendantOfRoots(parent) && parent->id().connection_id != id_) 263 if (!IsNodeDescendantOfRoots(parent) && parent->id().connection_id != id_)
267 return false; // |parent| is not visible to this connection. 264 return false; // |parent| is not visible to this connection.
268 265
269 // Allow the add if the child is already a descendant of the roots or was 266 // Only allow the add if we haven't given one of the ancestors of |parent| to
270 // created by this connection. 267 // another node. That is, Embed() hasn't been invoked with one of our nodes.
271 return (IsNodeDescendantOfRoots(child) || child->id().connection_id == id_); 268 return !IsNodeEmbeddedInAnotherConnection(parent);
272 } 269 }
273 270
274 bool ViewManagerServiceImpl::CanReorderNode(const Node* node, 271 bool ViewManagerServiceImpl::CanReorderNode(const Node* node,
275 const Node* relative_node, 272 const Node* relative_node,
276 OrderDirection direction) const { 273 OrderDirection direction) const {
277 if (!node || !relative_node) 274 if (!node || !relative_node)
278 return false; 275 return false;
279 276
280 if (node->id().connection_id != id_) 277 if (node->id().connection_id != id_)
281 return false; 278 return false;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 const View* view = GetView(view_id); 314 const View* view = GetView(view_id);
318 return (view && view_id.connection_id == id_) || view_id == ViewId(); 315 return (view && view_id.connection_id == id_) || view_id == ViewId();
319 } 316 }
320 317
321 bool ViewManagerServiceImpl::CanSetFocus(const Node* node) const { 318 bool ViewManagerServiceImpl::CanSetFocus(const Node* node) const {
322 // TODO(beng): security. 319 // TODO(beng): security.
323 return true; 320 return true;
324 } 321 }
325 322
326 bool ViewManagerServiceImpl::CanGetNodeTree(const Node* node) const { 323 bool ViewManagerServiceImpl::CanGetNodeTree(const Node* node) const {
327 return node && 324 if (!node)
328 (IsNodeDescendantOfRoots(node) || node->id().connection_id == id_); 325 return false;
326
327 if (roots_.empty())
328 return true;
329
330 if (node->id().connection_id == id_)
331 return true;
332
333 return roots_.count(NodeIdToTransportId(node->id())) > 0;
329 } 334 }
330 335
331 bool ViewManagerServiceImpl::CanEmbed(Id transport_node_id) const { 336 bool ViewManagerServiceImpl::CanEmbed(Id transport_node_id) const {
332 const Node* node = GetNode(NodeIdFromTransportId(transport_node_id)); 337 const Node* node = GetNode(NodeIdFromTransportId(transport_node_id));
333 return node && node->id().connection_id == id_; 338 return node && node->id().connection_id == id_;
334 } 339 }
335 340
336 bool ViewManagerServiceImpl::CanSetNodeVisibility(const Node* node, 341 bool ViewManagerServiceImpl::CanSetNodeVisibility(const Node* node,
337 bool visibile) const { 342 bool visibile) const {
338 return node && 343 return node &&
339 (node->id().connection_id == id_ || 344 (node->id().connection_id == id_ ||
340 roots_.find(NodeIdToTransportId(node->id())) != roots_.end()) && 345 roots_.find(NodeIdToTransportId(node->id())) != roots_.end()) &&
341 node->IsVisible() != visibile; 346 node->IsVisible() != visibile;
342 } 347 }
343 348
349 bool ViewManagerServiceImpl::CanDescendIntoNodeForNodeTree(
350 const Node* node) const {
351 if (roots_.empty())
352 return true;
353
354 ViewManagerServiceImpl* connection =
355 root_node_manager_->GetConnectionWithRoot(node->id());
356 return !connection || connection == this;
357 }
358
344 bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source, 359 bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source,
345 const NodeId& node_id) { 360 const NodeId& node_id) {
346 DCHECK_EQ(node_id.connection_id, id_); 361 DCHECK_EQ(node_id.connection_id, id_);
347 Node* node = GetNode(node_id); 362 Node* node = GetNode(node_id);
348 if (!node) 363 if (!node)
349 return false; 364 return false;
350 RootNodeManager::ScopedChange change(source, root_node_manager_, true); 365 RootNodeManager::ScopedChange change(source, root_node_manager_, true);
351 delete node; 366 delete node;
352 return true; 367 return true;
353 } 368 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 if (local_nodes) 412 if (local_nodes)
398 local_nodes->push_back(GetNode(node->id())); 413 local_nodes->push_back(GetNode(node->id()));
399 return; 414 return;
400 } 415 }
401 known_nodes_.erase(NodeIdToTransportId(node->id())); 416 known_nodes_.erase(NodeIdToTransportId(node->id()));
402 std::vector<const Node*> children = node->GetChildren(); 417 std::vector<const Node*> children = node->GetChildren();
403 for (size_t i = 0; i < children.size(); ++i) 418 for (size_t i = 0; i < children.size(); ++i)
404 RemoveFromKnown(children[i], local_nodes); 419 RemoveFromKnown(children[i], local_nodes);
405 } 420 }
406 421
422 bool ViewManagerServiceImpl::IsNodeEmbeddedInAnotherConnection(
423 const Node* node) const {
424 while (node) {
425 const ViewManagerServiceImpl* connection =
426 root_node_manager_->GetConnectionWithRoot(node->id());
427 if (connection)
428 return connection != this;
429 node = node->GetParent();
430 }
431 return false;
432 }
433
407 void ViewManagerServiceImpl::AddRoot(const NodeId& node_id) { 434 void ViewManagerServiceImpl::AddRoot(const NodeId& node_id) {
408 const Id transport_node_id(NodeIdToTransportId(node_id)); 435 const Id transport_node_id(NodeIdToTransportId(node_id));
409 CHECK(roots_.count(transport_node_id) == 0); 436 CHECK(roots_.count(transport_node_id) == 0);
410 437
411 std::vector<const Node*> to_send; 438 std::vector<const Node*> to_send;
412 CHECK_EQ(creator_id_, node_id.connection_id); 439 CHECK_EQ(creator_id_, node_id.connection_id);
413 roots_.insert(transport_node_id); 440 roots_.insert(transport_node_id);
414 Node* node = GetNode(node_id); 441 Node* node = GetNode(node_id);
415 CHECK(node); 442 CHECK(node);
416 if (known_nodes_.count(transport_node_id) == 0) { 443 if (known_nodes_.count(transport_node_id) == 0) {
(...skipping 24 matching lines...) Expand all
441 root_node_manager_->OnConnectionMessagedClient(id_); 468 root_node_manager_->OnConnectionMessagedClient(id_);
442 469
443 // This connection no longer knows about the node. Unparent any nodes that 470 // This connection no longer knows about the node. Unparent any nodes that
444 // were parented to nodes in the root. 471 // were parented to nodes in the root.
445 std::vector<Node*> local_nodes; 472 std::vector<Node*> local_nodes;
446 RemoveFromKnown(GetNode(node_id), &local_nodes); 473 RemoveFromKnown(GetNode(node_id), &local_nodes);
447 for (size_t i = 0; i < local_nodes.size(); ++i) 474 for (size_t i = 0; i < local_nodes.size(); ++i)
448 local_nodes[i]->GetParent()->Remove(local_nodes[i]); 475 local_nodes[i]->GetParent()->Remove(local_nodes[i]);
449 } 476 }
450 477
478 void ViewManagerServiceImpl::RemoveChildrenAsPartOfEmbed(
479 const NodeId& node_id) {
480 // Let the root do what it wants.
481 if (roots_.empty())
482 return;
483
484 Node* node = GetNode(node_id);
485 CHECK(node);
486 CHECK(node->id().connection_id == node_id.connection_id);
487 std::vector<Node*> children = node->GetChildren();
488 for (size_t i = 0; i < children.size(); ++i)
489 node->Remove(children[i]);
490 }
491
451 bool ViewManagerServiceImpl::IsNodeDescendantOfRoots(const Node* node) const { 492 bool ViewManagerServiceImpl::IsNodeDescendantOfRoots(const Node* node) const {
452 if (roots_.empty()) 493 if (roots_.empty())
453 return true; 494 return true;
454 if (!node) 495 if (!node)
455 return false; 496 return false;
456 const Id invalid_node_id = 497 const Id invalid_node_id = NodeIdToTransportId(InvalidNodeId());
457 NodeIdToTransportId(InvalidNodeId());
458 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) { 498 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) {
459 if (*i == invalid_node_id) 499 if (*i == invalid_node_id)
460 continue; 500 continue;
461 const Node* root = GetNode(NodeIdFromTransportId(*i)); 501 const Node* root = GetNode(NodeIdFromTransportId(*i));
462 DCHECK(root); 502 DCHECK(root);
463 if (root->Contains(node)) 503 if (root->Contains(node))
464 return true; 504 return true;
465 } 505 }
466 return false; 506 return false;
467 } 507 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 inode->parent_id = NodeIdToTransportId(parent ? parent->id() : NodeId()); 566 inode->parent_id = NodeIdToTransportId(parent ? parent->id() : NodeId());
527 inode->node_id = NodeIdToTransportId(node->id()); 567 inode->node_id = NodeIdToTransportId(node->id());
528 inode->view_id = 568 inode->view_id =
529 ViewIdToTransportId(node->view() ? node->view()->id() : ViewId()); 569 ViewIdToTransportId(node->view() ? node->view()->id() : ViewId());
530 inode->bounds = Rect::From(node->bounds()); 570 inode->bounds = Rect::From(node->bounds());
531 array[i] = inode.Pass(); 571 array[i] = inode.Pass();
532 } 572 }
533 return array.Pass(); 573 return array.Pass();
534 } 574 }
535 575
576 void ViewManagerServiceImpl::GetNodeTreeImpl(
577 const Node* node,
578 std::vector<const Node*>* nodes) const {
579 DCHECK(node);
580
581 if (!CanGetNodeTree(node))
582 return;
583
584 nodes->push_back(node);
585
586 if (!CanDescendIntoNodeForNodeTree(node))
587 return;
588
589 std::vector<const Node*> children(node->GetChildren());
590 for (size_t i = 0 ; i < children.size(); ++i)
591 GetNodeTreeImpl(children[i], nodes);
592 }
593
536 void ViewManagerServiceImpl::CreateNode( 594 void ViewManagerServiceImpl::CreateNode(
537 Id transport_node_id, 595 Id transport_node_id,
538 const Callback<void(ErrorCode)>& callback) { 596 const Callback<void(ErrorCode)>& callback) {
539 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); 597 const NodeId node_id(NodeIdFromTransportId(transport_node_id));
540 ErrorCode error_code = ERROR_CODE_NONE; 598 ErrorCode error_code = ERROR_CODE_NONE;
541 if (node_id.connection_id != id_) { 599 if (node_id.connection_id != id_) {
542 error_code = ERROR_CODE_ILLEGAL_ARGUMENT; 600 error_code = ERROR_CODE_ILLEGAL_ARGUMENT;
543 } else if (node_map_.find(node_id.node_id) != node_map_.end()) { 601 } else if (node_map_.find(node_id.node_id) != node_map_.end()) {
544 error_code = ERROR_CODE_VALUE_IN_USE; 602 error_code = ERROR_CODE_VALUE_IN_USE;
545 } else { 603 } else {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 } 663 }
606 callback.Run(success); 664 callback.Run(success);
607 } 665 }
608 666
609 void ViewManagerServiceImpl::GetNodeTree( 667 void ViewManagerServiceImpl::GetNodeTree(
610 Id node_id, 668 Id node_id,
611 const Callback<void(Array<NodeDataPtr>)>& callback) { 669 const Callback<void(Array<NodeDataPtr>)>& callback) {
612 Node* node = GetNode(NodeIdFromTransportId(node_id)); 670 Node* node = GetNode(NodeIdFromTransportId(node_id));
613 std::vector<const Node*> nodes; 671 std::vector<const Node*> nodes;
614 if (CanGetNodeTree(node)) { 672 if (CanGetNodeTree(node)) {
615 GetDescendants(node, &nodes); 673 GetNodeTreeImpl(node, &nodes);
674 #if !defined(NDEBUG)
616 for (size_t i = 0; i < nodes.size(); ++i) 675 for (size_t i = 0; i < nodes.size(); ++i)
617 known_nodes_.insert(NodeIdToTransportId(nodes[i]->id())); 676 DCHECK_GT(known_nodes_.count(NodeIdToTransportId(nodes[i]->id())), 0u);
677 #endif
618 } 678 }
619 callback.Run(NodesToNodeDatas(nodes)); 679 callback.Run(NodesToNodeDatas(nodes));
620 } 680 }
621 681
622 void ViewManagerServiceImpl::CreateView( 682 void ViewManagerServiceImpl::CreateView(
623 Id transport_view_id, 683 Id transport_view_id,
624 const Callback<void(bool)>& callback) { 684 const Callback<void(bool)>& callback) {
625 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); 685 const ViewId view_id(ViewIdFromTransportId(transport_view_id));
626 if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) { 686 if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) {
627 callback.Run(false); 687 callback.Run(false);
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 // Only allow a node to be the root for one connection. 796 // Only allow a node to be the root for one connection.
737 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); 797 const NodeId node_id(NodeIdFromTransportId(transport_node_id));
738 ViewManagerServiceImpl* connection_by_url = 798 ViewManagerServiceImpl* connection_by_url =
739 root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>()); 799 root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>());
740 ViewManagerServiceImpl* connection_with_node_as_root = 800 ViewManagerServiceImpl* connection_with_node_as_root =
741 root_node_manager_->GetConnectionWithRoot(node_id); 801 root_node_manager_->GetConnectionWithRoot(node_id);
742 if ((connection_by_url != connection_with_node_as_root || 802 if ((connection_by_url != connection_with_node_as_root ||
743 (!connection_by_url && !connection_with_node_as_root)) && 803 (!connection_by_url && !connection_with_node_as_root)) &&
744 (!connection_by_url || !connection_by_url->HasRoot(node_id))) { 804 (!connection_by_url || !connection_by_url->HasRoot(node_id))) {
745 RootNodeManager::ScopedChange change(this, root_node_manager_, true); 805 RootNodeManager::ScopedChange change(this, root_node_manager_, true);
806 RemoveChildrenAsPartOfEmbed(node_id);
746 // Never message the originating connection. 807 // Never message the originating connection.
747 root_node_manager_->OnConnectionMessagedClient(id_); 808 root_node_manager_->OnConnectionMessagedClient(id_);
748 if (connection_with_node_as_root) 809 if (connection_with_node_as_root)
749 connection_with_node_as_root->RemoveRoot(node_id); 810 connection_with_node_as_root->RemoveRoot(node_id);
750 if (connection_by_url) 811 if (connection_by_url)
751 connection_by_url->AddRoot(node_id); 812 connection_by_url->AddRoot(node_id);
752 else 813 else
753 root_node_manager_->Embed(id_, url, transport_node_id); 814 root_node_manager_->Embed(id_, url, transport_node_id);
754 } else { 815 } else {
755 success = false; 816 success = false;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 850
790 client()->OnViewManagerConnectionEstablished( 851 client()->OnViewManagerConnectionEstablished(
791 id_, 852 id_,
792 creator_url_, 853 creator_url_,
793 NodesToNodeDatas(to_send)); 854 NodesToNodeDatas(to_send));
794 } 855 }
795 856
796 } // namespace service 857 } // namespace service
797 } // namespace view_manager 858 } // namespace view_manager
798 } // namespace mojo 859 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/services/view_manager/view_manager_service_impl.h ('k') | mojo/services/view_manager/view_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698