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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: mojo/services/view_manager/view_manager_connection.cc
diff --git a/mojo/services/view_manager/view_manager_connection.cc b/mojo/services/view_manager/view_manager_connection.cc
index f4384b86cb8bcfe1b8e0908c1dff13583fb56673..6caf9a1f253241c97e8dbeaf36496d5f9bbbc837 100644
--- a/mojo/services/view_manager/view_manager_connection.cc
+++ b/mojo/services/view_manager/view_manager_connection.cc
@@ -8,7 +8,6 @@
#include "mojo/public/cpp/bindings/allocation_scope.h"
#include "mojo/services/view_manager/node.h"
#include "mojo/services/view_manager/root_node_manager.h"
-#include "mojo/services/view_manager/type_converters.h"
#include "mojo/services/view_manager/view.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/aura/window.h"
@@ -67,7 +66,7 @@ void ViewManagerConnection::OnConnectionEstablished() {
client()->OnConnectionEstablished(
id_,
root_node_manager_->next_server_change_id(),
- Array<INode>::From(to_send));
+ NodesToINodes(to_send));
}
const Node* ViewManagerConnection::GetNode(const NodeId& id) const {
@@ -92,10 +91,24 @@ void ViewManagerConnection::ProcessNodeHierarchyChanged(
const Node* old_parent,
TransportChangeId server_change_id,
bool originated_change) {
+ if (known_nodes_.count(NodeIdToTransportId(node->id())) > 0) {
+ if (originated_change)
+ return;
+ 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);
+ client()->OnNodeDeleted(NodeIdToTransportId(node->id()),
+ server_change_id);
+ return;
+ }
+ }
+
if (originated_change || root_node_manager_->is_processing_delete_node())
return;
std::vector<const Node*> to_send;
- if (!ShouldNotifyOnHierarchyChange(node, new_parent, old_parent, &to_send)) {
+ if (!ShouldNotifyOnHierarchyChange(node, &new_parent, &old_parent,
+ &to_send)) {
if (root_node_manager_->IsProcessingChange()) {
client()->OnServerChangeIdAdvanced(
root_node_manager_->next_server_change_id() + 1);
@@ -105,11 +118,15 @@ void ViewManagerConnection::ProcessNodeHierarchyChanged(
AllocationScope allocation_scope;
const NodeId new_parent_id(new_parent ? new_parent->id() : NodeId());
const NodeId old_parent_id(old_parent ? old_parent->id() : NodeId());
+ DCHECK((node->id().connection_id == id_) ||
+ (roots_.count(NodeIdToTransportId(node->id())) > 0) ||
+ (new_parent && IsNodeDescendantOfRoots(new_parent)) ||
+ (old_parent && IsNodeDescendantOfRoots(old_parent)));
client()->OnNodeHierarchyChanged(NodeIdToTransportId(node->id()),
NodeIdToTransportId(new_parent_id),
NodeIdToTransportId(old_parent_id),
server_change_id,
- Array<INode>::From(to_send));
+ NodesToINodes(to_send));
}
void ViewManagerConnection::ProcessNodeViewReplaced(
@@ -117,16 +134,14 @@ void ViewManagerConnection::ProcessNodeViewReplaced(
const View* new_view,
const View* old_view,
bool originated_change) {
- if (originated_change)
+ if (originated_change || !known_nodes_.count(NodeIdToTransportId(node->id())))
return;
- if (known_nodes_.count(NodeIdToTransportId(node->id())) > 0) {
- const TransportViewId new_view_id = new_view ?
- ViewIdToTransportId(new_view->id()) : 0;
- const TransportViewId old_view_id = old_view ?
- ViewIdToTransportId(old_view->id()) : 0;
- client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()),
- new_view_id, old_view_id);
- }
+ const TransportViewId new_view_id = new_view ?
+ ViewIdToTransportId(new_view->id()) : 0;
+ const TransportViewId old_view_id = old_view ?
+ ViewIdToTransportId(old_view->id()) : 0;
+ client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()),
+ new_view_id, old_view_id);
}
void ViewManagerConnection::ProcessNodeDeleted(
@@ -231,29 +246,66 @@ void ViewManagerConnection::GetUnknownNodesFrom(
GetUnknownNodesFrom(children[i], nodes);
}
+void ViewManagerConnection::RemoveFromKnown(const Node* node) {
+ if (node->id().connection_id == 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]);
+}
+
+bool ViewManagerConnection::IsNodeDescendantOfRoots(const Node* node) const {
+ if (roots_.empty())
+ return true;
+ if (!node)
+ return false;
+ for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) {
+ const Node* root = GetNode(NodeIdFromTransportId(*i));
+ DCHECK(root);
+ if (root->Contains(node))
+ return true;
+ }
+ return false;
+}
+
bool ViewManagerConnection::ShouldNotifyOnHierarchyChange(
const Node* node,
- const Node* new_parent,
- const Node* old_parent,
+ const Node** new_parent,
+ const Node** old_parent,
std::vector<const Node*>* to_send) {
- if (new_parent) {
+ // If the node is not in |roots_| or was never known to this connection then
+ // don't notify the client about it.
+ if (node->id().connection_id != id_ &&
+ known_nodes_.count(NodeIdToTransportId(node->id())) == 0 &&
+ !IsNodeDescendantOfRoots(node)) {
+ return false;
+ }
+ if (!IsNodeDescendantOfRoots(*new_parent))
+ *new_parent = NULL;
+ if (!IsNodeDescendantOfRoots(*old_parent))
+ *old_parent = NULL;
+
+ if (*new_parent) {
// On getting a new parent we may need to communicate new nodes to the
// client. We do that in the following cases:
- // . New parent is a descendant of the root. In this case the client already
- // knows all ancestors, so we only have to communicate descendants of node
- // the client doesn't know about.
+ // . New parent is a descendant of the roots. In this case the client
+ // already knows all ancestors, so we only have to communicate descendants
+ // of node the client doesn't know about.
// . If the client knew about the parent, we have to do the same.
// . If the client knows about the node and is added to a tree the client
// doesn't know about we have to communicate from the root down (the
// client is learning about a new root).
- if (root_node_manager_->root()->Contains(new_parent) ||
- known_nodes_.count(NodeIdToTransportId(new_parent->id()))) {
+ if (root_node_manager_->root()->Contains(*new_parent) ||
+ known_nodes_.count(NodeIdToTransportId((*new_parent)->id()))) {
GetUnknownNodesFrom(node, to_send);
return true;
}
// If parent wasn't known we have to communicate from the root down.
if (known_nodes_.count(NodeIdToTransportId(node->id()))) {
- GetUnknownNodesFrom(new_parent->GetRoot(), to_send);
+ // No need to check against |roots_| as client should always know it's
+ // |roots_|.
+ GetUnknownNodesFrom((*new_parent)->GetRoot(), to_send);
return true;
}
}
@@ -262,6 +314,62 @@ bool ViewManagerConnection::ShouldNotifyOnHierarchyChange(
return known_nodes_.count(NodeIdToTransportId(node->id())) > 0;
}
+bool ViewManagerConnection::ProcessSetRoots(
+ TransportConnectionId source_connection_id,
+ const Array<TransportNodeId>& transport_node_ids) {
+ // TODO(sky): these DCHECKs can go away once this is part of a real API. Also
+ // make sure that when roots are set nodes are communicate to client. Code in
+ // ProcessNodeHierarchyChanged() is depending on this.
+ DCHECK(node_map_.empty());
+ DCHECK(view_map_.empty());
+
+ NodeIdSet roots;
+ for (size_t i = 0; i < transport_node_ids.size(); ++i) {
+ const Node* node = GetNode(NodeIdFromTransportId(transport_node_ids[i]));
+ // Only allow setting roots that are owned by the source connection.
+ if (!node || node->id().connection_id != source_connection_id)
+ return false;
+ roots.insert(transport_node_ids[i]);
+ }
+ roots_.swap(roots);
+
+ // TODO(sky): remove |known_nodes_.clear()| temporary while this is done here
+ // instead of at creation time.
+ known_nodes_.clear();
+ std::vector<const Node*> to_send;
+ for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i)
+ GetUnknownNodesFrom(GetNode(NodeIdFromTransportId(*i)), &to_send);
+ AllocationScope allocation_scope;
+ client()->OnConnectionEstablished(
+ id_,
+ root_node_manager_->next_server_change_id(),
+ NodesToINodes(to_send));
+
+ return true;
+}
+
+Array<INode> ViewManagerConnection::NodesToINodes(
+ const std::vector<const Node*>& nodes) {
+ Array<INode>::Builder array_builder(nodes.size());
+ for (size_t i = 0; i < nodes.size(); ++i) {
+ INode::Builder node_builder;
+ const Node* node = nodes[i];
+ DCHECK(known_nodes_.count(NodeIdToTransportId(node->id())) > 0);
+ const Node* parent = node->GetParent();
+ // If the parent isn't known, it means the parent is not visible to us (not
+ // in roots), and should not be sent over.
+ if (parent && known_nodes_.count(NodeIdToTransportId(parent->id())) == 0)
+ parent = NULL;
+ node_builder.set_parent_id(NodeIdToTransportId(
+ parent ? parent->id() : NodeId()));
+ node_builder.set_node_id(NodeIdToTransportId(node->id()));
+ node_builder.set_view_id(ViewIdToTransportId(
+ node->view() ? node->view()->id() : ViewId()));
+ array_builder[i] = node_builder.Finish();
+ }
+ return array_builder.Finish();
+}
+
void ViewManagerConnection::CreateNode(
TransportNodeId transport_node_id,
const Callback<void(bool)>& callback) {
@@ -338,7 +446,7 @@ void ViewManagerConnection::GetNodeTree(
GetDescendants(node, &nodes);
for (size_t i = 0; i < nodes.size(); ++i)
known_nodes_.insert(NodeIdToTransportId(nodes[i]->id()));
- callback.Run(Array<INode>::From(nodes));
+ callback.Run(NodesToINodes(nodes));
}
void ViewManagerConnection::CreateView(
@@ -393,6 +501,16 @@ void ViewManagerConnection::SetViewContents(
UnmapBuffer(handle_data);
}
+void ViewManagerConnection::SetRoots(
+ TransportConnectionId connection_id,
+ const Array<TransportNodeId>& transport_node_ids,
+ const Callback<void(bool)>& callback) {
+ ViewManagerConnection* connection =
+ root_node_manager_->GetConnection(connection_id);
+ callback.Run(connection &&
+ connection->ProcessSetRoots(id_, transport_node_ids));
+}
+
void ViewManagerConnection::OnNodeHierarchyChanged(const Node* node,
const Node* new_parent,
const Node* old_parent) {
« 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