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

Unified Diff: mojo/services/view_manager/view_manager_service_impl.cc

Issue 397803003: Makes it so a node can only the root of one connection at a time (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge again 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 b98b99dbe53b97939086409b03b8bca683febced..793a4543d0377a8629dee853f01de02a6e227f64 100644
--- a/mojo/services/view_manager/view_manager_service_impl.cc
+++ b/mojo/services/view_manager/view_manager_service_impl.cc
@@ -86,6 +86,10 @@ const View* ViewManagerServiceImpl::GetView(const ViewId& id) const {
return root_node_manager_->GetView(id);
}
+bool ViewManagerServiceImpl::HasRoot(const NodeId& id) const {
+ return roots_.find(NodeIdToTransportId(id)) != roots_.end();
+}
+
void ViewManagerServiceImpl::OnViewManagerServiceImplDestroyed(
ConnectionSpecificId id) {
if (creator_id_ == id)
@@ -119,7 +123,7 @@ void ViewManagerServiceImpl::ProcessNodeHierarchyChanged(
if (node->id().connection_id != id_ && !IsNodeDescendantOfRoots(node)) {
// Node was a descendant of roots and is no longer, treat it as though the
// node was deleted.
- RemoveFromKnown(node);
+ RemoveFromKnown(node, NULL);
client()->OnNodeDeleted(NodeIdToTransportId(node->id()),
server_change_id);
root_node_manager_->OnConnectionMessagedClient(id_);
@@ -407,21 +411,24 @@ void ViewManagerServiceImpl::GetUnknownNodesFrom(
GetUnknownNodesFrom(children[i], nodes);
}
-void ViewManagerServiceImpl::RemoveFromKnown(const Node* node) {
- if (node->id().connection_id == id_)
+void ViewManagerServiceImpl::RemoveFromKnown(const Node* node,
+ std::vector<Node*>* local_nodes) {
+ if (node->id().connection_id == id_) {
+ if (local_nodes)
+ local_nodes->push_back(GetNode(node->id()));
return;
+ }
known_nodes_.erase(NodeIdToTransportId(node->id()));
std::vector<const Node*> children = node->GetChildren();
for (size_t i = 0; i < children.size(); ++i)
- RemoveFromKnown(children[i]);
+ RemoveFromKnown(children[i], local_nodes);
}
-bool ViewManagerServiceImpl::AddRoot(Id transport_node_id) {
- if (roots_.count(transport_node_id) > 0)
- return false;
+void ViewManagerServiceImpl::AddRoot(const NodeId& node_id) {
+ const Id transport_node_id(NodeIdToTransportId(node_id));
+ CHECK(roots_.count(transport_node_id) == 0);
std::vector<const Node*> to_send;
- const NodeId node_id(NodeIdFromTransportId(transport_node_id));
CHECK_EQ(creator_id_, node_id.connection_id);
roots_.insert(transport_node_id);
Node* node = GetNode(node_id);
@@ -435,7 +442,31 @@ bool ViewManagerServiceImpl::AddRoot(Id transport_node_id) {
}
client()->OnRootAdded(NodesToNodeDatas(to_send));
- return true;
+ root_node_manager_->OnConnectionMessagedClient(id_);
+}
+
+void ViewManagerServiceImpl::RemoveRoot(const NodeId& node_id) {
+ const Id transport_node_id(NodeIdToTransportId(node_id));
+ CHECK(roots_.count(transport_node_id) > 0);
+
+ roots_.erase(transport_node_id);
+ if (roots_.empty())
+ roots_.insert(NodeIdToTransportId(InvalidNodeId()));
+
+ // No need to do anything if we created the node.
+ if (node_id.connection_id == id_)
+ return;
+
+ client()->OnNodeDeleted(transport_node_id,
+ root_node_manager_->next_server_change_id());
+ root_node_manager_->OnConnectionMessagedClient(id_);
+
+ // This connection no longer knows about the node. Unparent any nodes that
+ // were parented to nodes in the root.
+ std::vector<Node*> local_nodes;
+ RemoveFromKnown(GetNode(node_id), &local_nodes);
+ for (size_t i = 0; i < local_nodes.size(); ++i)
+ local_nodes[i]->GetParent()->Remove(local_nodes[i]);
}
bool ViewManagerServiceImpl::IsNodeDescendantOfRoots(const Node* node) const {
@@ -737,13 +768,30 @@ void ViewManagerServiceImpl::Embed(const String& url,
const Callback<void(bool)>& callback) {
bool success = CanEmbed(transport_node_id);
if (success) {
- // We may already have this connection, if so reuse it.
- ViewManagerServiceImpl* existing_connection =
+ // Only allow a node to be the root for one connection.
+ const NodeId node_id(NodeIdFromTransportId(transport_node_id));
+ ViewManagerServiceImpl* connection_by_url =
root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>());
- if (existing_connection)
- success = existing_connection->AddRoot(transport_node_id);
- else
- root_node_manager_->Embed(id_, url, transport_node_id);
+ ViewManagerServiceImpl* connection_with_node_as_root =
+ root_node_manager_->GetConnectionWithRoot(node_id);
+ if ((connection_by_url != connection_with_node_as_root ||
+ (!connection_by_url && !connection_with_node_as_root)) &&
+ (!connection_by_url || !connection_by_url->HasRoot(node_id))) {
+ RootNodeManager::ScopedChange change(
+ this, root_node_manager_,
+ RootNodeManager::CHANGE_TYPE_ADVANCE_SERVER_CHANGE_ID, true);
+ // Never message the originating connection.
+ root_node_manager_->OnConnectionMessagedClient(id_);
+ if (connection_with_node_as_root)
+ connection_with_node_as_root->RemoveRoot(node_id);
+ if (connection_by_url)
+ connection_by_url->AddRoot(node_id);
+ else
+ root_node_manager_->Embed(id_, url, transport_node_id);
+ change.SendServerChangeIdAdvanced();
+ } else {
+ success = false;
+ }
}
callback.Run(success);
}
« 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