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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: mojo/services/view_manager/view_manager_service_impl.cc
diff --git a/mojo/services/view_manager/view_manager_service_impl.cc b/mojo/services/view_manager/view_manager_service_impl.cc
index 96cf1021eabcee262b2b57231782b32b16d08949..1f169b9f3c1e07637979fd40aeca2346a209aad3 100644
--- a/mojo/services/view_manager/view_manager_service_impl.cc
+++ b/mojo/services/view_manager/view_manager_service_impl.cc
@@ -17,21 +17,6 @@
namespace mojo {
namespace view_manager {
namespace service {
-namespace {
-
-// Places |node| in |nodes| and recurses through the children.
-void GetDescendants(const Node* node, std::vector<const Node*>* nodes) {
- if (!node)
- return;
-
- nodes->push_back(node);
-
- std::vector<const Node*> children(node->GetChildren());
- for (size_t i = 0 ; i < children.size(); ++i)
- GetDescendants(children[i], nodes);
-}
-
-} // namespace
ViewManagerServiceImpl::ViewManagerServiceImpl(
RootNodeManager* root_node_manager,
@@ -241,15 +226,24 @@ bool ViewManagerServiceImpl::CanRemoveNodeFromParent(const Node* node) const {
if (!parent)
return false;
- // Always allow the remove if there are no roots. Otherwise the remove is
- // allowed if the parent is a descendant of the roots, or the node and its
- // parent were created by this connection. We explicitly disallow removal of
- // the node from its parent if the parent isn't visible to this connection
- // (not in roots).
- return (roots_.empty() ||
- (IsNodeDescendantOfRoots(parent) ||
- (node->id().connection_id == id_ &&
- parent->id().connection_id == id_)));
+ if (roots_.empty())
+ return true; // Root can do anything.
+
+ if (node->id().connection_id != id_)
+ return false; // Can only unparent nodes we created.
+
+ if (roots_.count(NodeIdToTransportId(parent->id())) > 0)
+ return true; // We can always remove from one of our roots.
+
+ // Don't allow removing from nodes from other connections that aren't in our
+ // root list.
+ if (parent->id().connection_id != id_)
+ return false;
+
+ // Allow the remove as long as we haven't embedded another node at |parent|.
+ ViewManagerServiceImpl* connection =
+ root_node_manager_->GetConnectionWithRoot(parent->id());
+ return !connection || connection == this;
}
bool ViewManagerServiceImpl::CanAddNode(const Node* parent,
@@ -263,12 +257,15 @@ bool ViewManagerServiceImpl::CanAddNode(const Node* parent,
if (roots_.empty())
return true; // No restriction if there are no roots.
+ if (child->id().connection_id != id_)
+ return false; // Can't move children from different connections.
+
if (!IsNodeDescendantOfRoots(parent) && parent->id().connection_id != id_)
return false; // |parent| is not visible to this connection.
- // Allow the add if the child is already a descendant of the roots or was
- // created by this connection.
- return (IsNodeDescendantOfRoots(child) || child->id().connection_id == id_);
+ // Only allow the add if we haven't given one of the ancestors of |parent| to
+ // another node. That is, Embed() hasn't been invoked with one of our nodes.
+ return !IsNodeEmbeddedInAnotherConnection(parent);
}
bool ViewManagerServiceImpl::CanReorderNode(const Node* node,
@@ -324,8 +321,16 @@ bool ViewManagerServiceImpl::CanSetFocus(const Node* node) const {
}
bool ViewManagerServiceImpl::CanGetNodeTree(const Node* node) const {
- return node &&
- (IsNodeDescendantOfRoots(node) || node->id().connection_id == id_);
+ if (!node)
+ return false;
+
+ if (roots_.empty())
+ return true;
+
+ if (node->id().connection_id == id_)
+ return true;
+
+ return roots_.count(NodeIdToTransportId(node->id())) > 0;
}
bool ViewManagerServiceImpl::CanEmbed(Id transport_node_id) const {
@@ -341,6 +346,16 @@ bool ViewManagerServiceImpl::CanSetNodeVisibility(const Node* node,
node->IsVisible() != visibile;
}
+bool ViewManagerServiceImpl::CanDescendIntoNodeForNodeTree(
+ const Node* node) const {
+ if (roots_.empty())
+ return true;
+
+ ViewManagerServiceImpl* connection =
+ root_node_manager_->GetConnectionWithRoot(node->id());
+ return !connection || connection == this;
+}
+
bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source,
const NodeId& node_id) {
DCHECK_EQ(node_id.connection_id, id_);
@@ -404,6 +419,18 @@ void ViewManagerServiceImpl::RemoveFromKnown(const Node* node,
RemoveFromKnown(children[i], local_nodes);
}
+bool ViewManagerServiceImpl::IsNodeEmbeddedInAnotherConnection(
+ const Node* node) const {
+ while (node) {
+ const ViewManagerServiceImpl* connection =
+ root_node_manager_->GetConnectionWithRoot(node->id());
+ if (connection)
+ return connection != this;
+ node = node->GetParent();
+ }
+ return false;
+}
+
void ViewManagerServiceImpl::AddRoot(const NodeId& node_id) {
const Id transport_node_id(NodeIdToTransportId(node_id));
CHECK(roots_.count(transport_node_id) == 0);
@@ -448,13 +475,26 @@ void ViewManagerServiceImpl::RemoveRoot(const NodeId& node_id) {
local_nodes[i]->GetParent()->Remove(local_nodes[i]);
}
+void ViewManagerServiceImpl::RemoveChildrenAsPartOfEmbed(
+ const NodeId& node_id) {
+ // Let the root do what it wants.
+ if (roots_.empty())
+ return;
+
+ Node* node = GetNode(node_id);
+ CHECK(node);
+ CHECK(node->id().connection_id == node_id.connection_id);
+ std::vector<Node*> children = node->GetChildren();
+ for (size_t i = 0; i < children.size(); ++i)
+ node->Remove(children[i]);
+}
+
bool ViewManagerServiceImpl::IsNodeDescendantOfRoots(const Node* node) const {
if (roots_.empty())
return true;
if (!node)
return false;
- const Id invalid_node_id =
- NodeIdToTransportId(InvalidNodeId());
+ const Id invalid_node_id = NodeIdToTransportId(InvalidNodeId());
for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) {
if (*i == invalid_node_id)
continue;
@@ -533,6 +573,24 @@ Array<NodeDataPtr> ViewManagerServiceImpl::NodesToNodeDatas(
return array.Pass();
}
+void ViewManagerServiceImpl::GetNodeTreeImpl(
+ const Node* node,
+ std::vector<const Node*>* nodes) const {
+ DCHECK(node);
+
+ if (!CanGetNodeTree(node))
+ return;
+
+ nodes->push_back(node);
+
+ if (!CanDescendIntoNodeForNodeTree(node))
+ return;
+
+ std::vector<const Node*> children(node->GetChildren());
+ for (size_t i = 0 ; i < children.size(); ++i)
+ GetNodeTreeImpl(children[i], nodes);
+}
+
void ViewManagerServiceImpl::CreateNode(
Id transport_node_id,
const Callback<void(ErrorCode)>& callback) {
@@ -612,9 +670,11 @@ void ViewManagerServiceImpl::GetNodeTree(
Node* node = GetNode(NodeIdFromTransportId(node_id));
std::vector<const Node*> nodes;
if (CanGetNodeTree(node)) {
- GetDescendants(node, &nodes);
+ GetNodeTreeImpl(node, &nodes);
+#if !defined(NDEBUG)
for (size_t i = 0; i < nodes.size(); ++i)
- known_nodes_.insert(NodeIdToTransportId(nodes[i]->id()));
+ DCHECK_GT(known_nodes_.count(NodeIdToTransportId(nodes[i]->id())), 0u);
+#endif
}
callback.Run(NodesToNodeDatas(nodes));
}
@@ -743,6 +803,7 @@ void ViewManagerServiceImpl::Embed(const String& url,
(!connection_by_url && !connection_with_node_as_root)) &&
(!connection_by_url || !connection_by_url->HasRoot(node_id))) {
RootNodeManager::ScopedChange change(this, root_node_manager_, true);
+ RemoveChildrenAsPartOfEmbed(node_id);
// Never message the originating connection.
root_node_manager_->OnConnectionMessagedClient(id_);
if (connection_with_node_as_root)
« 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