| OLD | NEW |
| 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/default_access_policy.h" |
| 10 #include "mojo/services/view_manager/node.h" | 11 #include "mojo/services/view_manager/node.h" |
| 11 #include "mojo/services/view_manager/root_node_manager.h" | 12 #include "mojo/services/view_manager/root_node_manager.h" |
| 12 #include "mojo/services/view_manager/view.h" | 13 #include "mojo/services/view_manager/view.h" |
| 14 #include "mojo/services/view_manager/window_manager_access_policy.h" |
| 13 #include "third_party/skia/include/core/SkBitmap.h" | 15 #include "third_party/skia/include/core/SkBitmap.h" |
| 14 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
| 15 #include "ui/gfx/codec/png_codec.h" | 17 #include "ui/gfx/codec/png_codec.h" |
| 16 | 18 |
| 17 namespace mojo { | 19 namespace mojo { |
| 18 namespace service { | 20 namespace service { |
| 19 | 21 |
| 20 ViewManagerServiceImpl::ViewManagerServiceImpl( | 22 ViewManagerServiceImpl::ViewManagerServiceImpl( |
| 21 RootNodeManager* root_node_manager, | 23 RootNodeManager* root_node_manager, |
| 22 ConnectionSpecificId creator_id, | 24 ConnectionSpecificId creator_id, |
| 23 const std::string& creator_url, | 25 const std::string& creator_url, |
| 24 const std::string& url, | 26 const std::string& url, |
| 25 const NodeId& root_id) | 27 const NodeId& root_id) |
| 26 : root_node_manager_(root_node_manager), | 28 : root_node_manager_(root_node_manager), |
| 27 id_(root_node_manager_->GetAndAdvanceNextConnectionId()), | 29 id_(root_node_manager_->GetAndAdvanceNextConnectionId()), |
| 28 url_(url), | 30 url_(url), |
| 29 creator_id_(creator_id), | 31 creator_id_(creator_id), |
| 30 creator_url_(creator_url), | 32 creator_url_(creator_url), |
| 31 delete_on_connection_error_(false) { | 33 delete_on_connection_error_(false) { |
| 34 // TODO: http://crbug.com/397660 . |
| 32 if (root_id != InvalidNodeId()) { | 35 if (root_id != InvalidNodeId()) { |
| 33 CHECK(GetNode(root_id)); | 36 CHECK(GetNode(root_id)); |
| 34 roots_.insert(NodeIdToTransportId(root_id)); | 37 roots_.insert(NodeIdToTransportId(root_id)); |
| 38 access_policy_.reset(new DefaultAccessPolicy(id_, this)); |
| 39 } else { |
| 40 access_policy_.reset(new WindowManagerAccessPolicy(id_, this)); |
| 35 } | 41 } |
| 36 } | 42 } |
| 37 | 43 |
| 38 ViewManagerServiceImpl::~ViewManagerServiceImpl() { | 44 ViewManagerServiceImpl::~ViewManagerServiceImpl() { |
| 39 // Delete any views we created. | 45 // Delete any views we created. |
| 40 while (!view_map_.empty()) { | 46 while (!view_map_.empty()) { |
| 41 bool result = DeleteViewImpl(this, view_map_.begin()->second->id()); | 47 bool result = DeleteViewImpl(this, view_map_.begin()->second); |
| 42 DCHECK(result); | 48 DCHECK(result); |
| 43 } | 49 } |
| 44 | 50 |
| 45 // Ditto the nodes. | 51 // Ditto the nodes. |
| 46 if (!node_map_.empty()) { | 52 if (!node_map_.empty()) { |
| 47 RootNodeManager::ScopedChange change(this, root_node_manager_, true); | 53 RootNodeManager::ScopedChange change(this, root_node_manager_, true); |
| 48 while (!node_map_.empty()) | 54 while (!node_map_.empty()) |
| 49 delete node_map_.begin()->second; | 55 delete node_map_.begin()->second; |
| 50 } | 56 } |
| 51 | 57 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 76 ConnectionSpecificId id) { | 82 ConnectionSpecificId id) { |
| 77 if (creator_id_ == id) | 83 if (creator_id_ == id) |
| 78 creator_id_ = kRootConnection; | 84 creator_id_ = kRootConnection; |
| 79 } | 85 } |
| 80 | 86 |
| 81 void ViewManagerServiceImpl::ProcessNodeBoundsChanged( | 87 void ViewManagerServiceImpl::ProcessNodeBoundsChanged( |
| 82 const Node* node, | 88 const Node* node, |
| 83 const gfx::Rect& old_bounds, | 89 const gfx::Rect& old_bounds, |
| 84 const gfx::Rect& new_bounds, | 90 const gfx::Rect& new_bounds, |
| 85 bool originated_change) { | 91 bool originated_change) { |
| 86 if (originated_change) | 92 if (originated_change || !IsNodeKnown(node)) |
| 87 return; | 93 return; |
| 88 Id node_id = NodeIdToTransportId(node->id()); | 94 client()->OnNodeBoundsChanged(NodeIdToTransportId(node->id()), |
| 89 if (known_nodes_.count(node_id) > 0) { | 95 Rect::From(old_bounds), |
| 90 client()->OnNodeBoundsChanged(node_id, | 96 Rect::From(new_bounds)); |
| 91 Rect::From(old_bounds), | |
| 92 Rect::From(new_bounds)); | |
| 93 } | |
| 94 } | 97 } |
| 95 | 98 |
| 96 void ViewManagerServiceImpl::ProcessNodeHierarchyChanged( | 99 void ViewManagerServiceImpl::ProcessNodeHierarchyChanged( |
| 97 const Node* node, | 100 const Node* node, |
| 98 const Node* new_parent, | 101 const Node* new_parent, |
| 99 const Node* old_parent, | 102 const Node* old_parent, |
| 100 bool originated_change) { | 103 bool originated_change) { |
| 101 if (known_nodes_.count(NodeIdToTransportId(node->id())) > 0) { | 104 if (originated_change || root_node_manager_->is_processing_delete_node() || |
| 102 if (originated_change) | 105 root_node_manager_->DidConnectionMessageClient(id_)) { |
| 103 return; | 106 return; |
| 104 if (node->id().connection_id != id_ && !IsNodeDescendantOfRoots(node)) { | |
| 105 // Node was a descendant of roots and is no longer, treat it as though the | |
| 106 // node was deleted. | |
| 107 RemoveFromKnown(node, NULL); | |
| 108 client()->OnNodeDeleted(NodeIdToTransportId(node->id())); | |
| 109 root_node_manager_->OnConnectionMessagedClient(id_); | |
| 110 return; | |
| 111 } | |
| 112 } | 107 } |
| 113 | 108 |
| 114 if (originated_change || root_node_manager_->is_processing_delete_node()) | 109 if (!access_policy_->ShouldNotifyOnHierarchyChange( |
| 115 return; | 110 node, &new_parent, &old_parent)) { |
| 116 std::vector<const Node*> to_send; | |
| 117 if (!ShouldNotifyOnHierarchyChange(node, &new_parent, &old_parent, | |
| 118 &to_send)) { | |
| 119 return; | 111 return; |
| 120 } | 112 } |
| 113 // Inform the client of any new nodes and update the set of nodes we know |
| 114 // about. |
| 115 std::vector<const Node*> to_send; |
| 116 if (!IsNodeKnown(node)) |
| 117 GetUnknownNodesFrom(node, &to_send); |
| 121 const NodeId new_parent_id(new_parent ? new_parent->id() : NodeId()); | 118 const NodeId new_parent_id(new_parent ? new_parent->id() : NodeId()); |
| 122 const NodeId old_parent_id(old_parent ? old_parent->id() : NodeId()); | 119 const NodeId old_parent_id(old_parent ? old_parent->id() : NodeId()); |
| 123 DCHECK((node->id().connection_id == id_) || | |
| 124 (roots_.count(NodeIdToTransportId(node->id())) > 0) || | |
| 125 (new_parent && IsNodeDescendantOfRoots(new_parent)) || | |
| 126 (old_parent && IsNodeDescendantOfRoots(old_parent))); | |
| 127 client()->OnNodeHierarchyChanged(NodeIdToTransportId(node->id()), | 120 client()->OnNodeHierarchyChanged(NodeIdToTransportId(node->id()), |
| 128 NodeIdToTransportId(new_parent_id), | 121 NodeIdToTransportId(new_parent_id), |
| 129 NodeIdToTransportId(old_parent_id), | 122 NodeIdToTransportId(old_parent_id), |
| 130 NodesToNodeDatas(to_send)); | 123 NodesToNodeDatas(to_send)); |
| 124 root_node_manager_->OnConnectionMessagedClient(id_); |
| 131 } | 125 } |
| 132 | 126 |
| 133 void ViewManagerServiceImpl::ProcessNodeReorder(const Node* node, | 127 void ViewManagerServiceImpl::ProcessNodeReorder(const Node* node, |
| 134 const Node* relative_node, | 128 const Node* relative_node, |
| 135 OrderDirection direction, | 129 OrderDirection direction, |
| 136 bool originated_change) { | 130 bool originated_change) { |
| 137 if (originated_change || | 131 if (originated_change || !IsNodeKnown(node) || !IsNodeKnown(relative_node)) |
| 138 !known_nodes_.count(NodeIdToTransportId(node->id())) || | |
| 139 !known_nodes_.count(NodeIdToTransportId(relative_node->id()))) { | |
| 140 return; | 132 return; |
| 141 } | |
| 142 | 133 |
| 143 client()->OnNodeReordered(NodeIdToTransportId(node->id()), | 134 client()->OnNodeReordered(NodeIdToTransportId(node->id()), |
| 144 NodeIdToTransportId(relative_node->id()), | 135 NodeIdToTransportId(relative_node->id()), |
| 145 direction); | 136 direction); |
| 146 } | 137 } |
| 147 | 138 |
| 148 void ViewManagerServiceImpl::ProcessNodeViewReplaced( | 139 void ViewManagerServiceImpl::ProcessNodeViewReplaced( |
| 149 const Node* node, | 140 const Node* node, |
| 150 const View* new_view, | 141 const View* new_view, |
| 151 const View* old_view, | 142 const View* old_view, |
| 152 bool originated_change) { | 143 bool originated_change) { |
| 153 if (originated_change || !known_nodes_.count(NodeIdToTransportId(node->id()))) | 144 if (originated_change || !IsNodeKnown(node) || |
| 145 root_node_manager_->is_processing_delete_node()) { |
| 154 return; | 146 return; |
| 147 } |
| 155 const Id new_view_id = new_view ? | 148 const Id new_view_id = new_view ? |
| 156 ViewIdToTransportId(new_view->id()) : 0; | 149 access_policy_->GetViewIdToSend(node, new_view) : 0; |
| 157 const Id old_view_id = old_view ? | 150 const Id old_view_id = old_view ? |
| 158 ViewIdToTransportId(old_view->id()) : 0; | 151 access_policy_->GetViewIdToSend(node, old_view) : 0; |
| 159 client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()), | 152 client()->OnNodeViewReplaced(NodeIdToTransportId(node->id()), |
| 160 new_view_id, old_view_id); | 153 new_view_id, old_view_id); |
| 161 } | 154 } |
| 162 | 155 |
| 163 void ViewManagerServiceImpl::ProcessNodeDeleted(const NodeId& node, | 156 void ViewManagerServiceImpl::ProcessNodeDeleted(const NodeId& node, |
| 164 bool originated_change) { | 157 bool originated_change) { |
| 165 node_map_.erase(node.node_id); | 158 node_map_.erase(node.node_id); |
| 166 | 159 |
| 167 const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0; | 160 const bool in_known = known_nodes_.erase(NodeIdToTransportId(node)) > 0; |
| 168 const bool in_roots = roots_.erase(NodeIdToTransportId(node)) > 0; | 161 const bool in_roots = roots_.erase(NodeIdToTransportId(node)) > 0; |
| 169 | 162 |
| 163 // TODO(sky): cleanup! |
| 170 if (in_roots && roots_.empty()) | 164 if (in_roots && roots_.empty()) |
| 171 roots_.insert(NodeIdToTransportId(InvalidNodeId())); | 165 roots_.insert(NodeIdToTransportId(InvalidNodeId())); |
| 172 | 166 |
| 173 if (originated_change) | 167 if (originated_change) |
| 174 return; | 168 return; |
| 175 | 169 |
| 176 if (in_known) { | 170 if (in_known) { |
| 177 client()->OnNodeDeleted(NodeIdToTransportId(node)); | 171 client()->OnNodeDeleted(NodeIdToTransportId(node)); |
| 178 root_node_manager_->OnConnectionMessagedClient(id_); | 172 root_node_manager_->OnConnectionMessagedClient(id_); |
| 179 } else if (root_node_manager_->IsProcessingChange() && | |
| 180 !root_node_manager_->DidConnectionMessageClient(id_)) { | |
| 181 root_node_manager_->OnConnectionMessagedClient(id_); | |
| 182 } | 173 } |
| 183 } | 174 } |
| 184 | 175 |
| 185 void ViewManagerServiceImpl::ProcessViewDeleted(const ViewId& view, | 176 void ViewManagerServiceImpl::ProcessViewDeleted(const ViewId& view, |
| 186 bool originated_change) { | 177 bool originated_change) { |
| 187 if (originated_change) | 178 if (!originated_change && access_policy_->ShouldSendViewDeleted(view)) |
| 188 return; | 179 client()->OnViewDeleted(ViewIdToTransportId(view)); |
| 189 client()->OnViewDeleted(ViewIdToTransportId(view)); | |
| 190 } | 180 } |
| 191 | 181 |
| 192 void ViewManagerServiceImpl::ProcessFocusChanged(const Node* focused_node, | 182 void ViewManagerServiceImpl::ProcessFocusChanged(const Node* focused_node, |
| 193 const Node* blurred_node, | 183 const Node* blurred_node, |
| 194 bool originated_change) { | 184 bool originated_change) { |
| 195 if (originated_change) | 185 if (originated_change) |
| 196 return; | 186 return; |
| 197 | 187 |
| 188 // TODO(sky): this should not notify all clients. |
| 198 Id focused_id = 0; | 189 Id focused_id = 0; |
| 199 Id blurred_id = 0; | 190 Id blurred_id = 0; |
| 200 if (focused_node) { | 191 if (focused_node && IsNodeKnown(focused_node)) |
| 201 Id focused_node_id = NodeIdToTransportId(focused_node->id()); | 192 focused_id = NodeIdToTransportId(focused_node->id()); |
| 202 if (known_nodes_.count(focused_node_id) > 0) | 193 if (blurred_node && IsNodeKnown(blurred_node)) |
| 203 focused_id = focused_node_id; | 194 blurred_id = NodeIdToTransportId(blurred_node->id()); |
| 204 } | |
| 205 if (blurred_node) { | |
| 206 Id blurred_node_id = NodeIdToTransportId(blurred_node->id()); | |
| 207 if (known_nodes_.count(blurred_node_id) > 0) | |
| 208 blurred_id = blurred_node_id; | |
| 209 } | |
| 210 | 195 |
| 211 if (focused_id != 0 || blurred_id != 0) | 196 if (focused_id != 0 || blurred_id != 0) |
| 212 client()->OnFocusChanged(focused_id, blurred_id); | 197 client()->OnFocusChanged(focused_id, blurred_id); |
| 213 } | 198 } |
| 214 | 199 |
| 215 void ViewManagerServiceImpl::OnConnectionError() { | 200 void ViewManagerServiceImpl::OnConnectionError() { |
| 216 if (delete_on_connection_error_) | 201 if (delete_on_connection_error_) |
| 217 delete this; | 202 delete this; |
| 218 } | 203 } |
| 219 | 204 |
| 220 bool ViewManagerServiceImpl::CanRemoveNodeFromParent(const Node* node) const { | 205 bool ViewManagerServiceImpl::IsNodeKnown(const Node* node) const { |
| 221 if (!node) | 206 return known_nodes_.count(NodeIdToTransportId(node->id())) > 0; |
| 222 return false; | |
| 223 | |
| 224 const Node* parent = node->GetParent(); | |
| 225 if (!parent) | |
| 226 return false; | |
| 227 | |
| 228 if (roots_.empty()) | |
| 229 return true; // Root can do anything. | |
| 230 | |
| 231 if (node->id().connection_id != id_) | |
| 232 return false; // Can only unparent nodes we created. | |
| 233 | |
| 234 if (roots_.count(NodeIdToTransportId(parent->id())) > 0) | |
| 235 return true; // We can always remove from one of our roots. | |
| 236 | |
| 237 // Don't allow removing from nodes from other connections that aren't in our | |
| 238 // root list. | |
| 239 if (parent->id().connection_id != id_) | |
| 240 return false; | |
| 241 | |
| 242 // Allow the remove as long as we haven't embedded another node at |parent|. | |
| 243 ViewManagerServiceImpl* connection = | |
| 244 root_node_manager_->GetConnectionWithRoot(parent->id()); | |
| 245 return !connection || connection == this; | |
| 246 } | |
| 247 | |
| 248 bool ViewManagerServiceImpl::CanAddNode(const Node* parent, | |
| 249 const Node* child) const { | |
| 250 if (!parent || !child) | |
| 251 return false; // Both nodes must be valid. | |
| 252 | |
| 253 if (child->GetParent() == parent || child->Contains(parent)) | |
| 254 return false; // Would result in an invalid hierarchy. | |
| 255 | |
| 256 if (roots_.empty()) | |
| 257 return true; // No restriction if there are no roots. | |
| 258 | |
| 259 if (child->id().connection_id != id_) | |
| 260 return false; // Can't move children from different connections. | |
| 261 | |
| 262 if (!IsNodeDescendantOfRoots(parent) && parent->id().connection_id != id_) | |
| 263 return false; // |parent| is not visible to this connection. | |
| 264 | |
| 265 // Only allow the add if we haven't given one of the ancestors of |parent| to | |
| 266 // another node. That is, Embed() hasn't been invoked with one of our nodes. | |
| 267 return !IsNodeEmbeddedInAnotherConnection(parent); | |
| 268 } | 207 } |
| 269 | 208 |
| 270 bool ViewManagerServiceImpl::CanReorderNode(const Node* node, | 209 bool ViewManagerServiceImpl::CanReorderNode(const Node* node, |
| 271 const Node* relative_node, | 210 const Node* relative_node, |
| 272 OrderDirection direction) const { | 211 OrderDirection direction) const { |
| 273 if (!node || !relative_node) | 212 if (!node || !relative_node) |
| 274 return false; | 213 return false; |
| 275 | 214 |
| 276 if (node->id().connection_id != id_) | |
| 277 return false; | |
| 278 | |
| 279 const Node* parent = node->GetParent(); | 215 const Node* parent = node->GetParent(); |
| 280 if (!parent || parent != relative_node->GetParent()) | 216 if (!parent || parent != relative_node->GetParent()) |
| 281 return false; | 217 return false; |
| 282 | 218 |
| 283 if (known_nodes_.count(NodeIdToTransportId(parent->id())) == 0) | 219 if (!access_policy_->CanReorderNode(node, relative_node, direction)) |
| 284 return false; | 220 return false; |
| 285 | 221 |
| 286 std::vector<const Node*> children = parent->GetChildren(); | 222 std::vector<const Node*> children = parent->GetChildren(); |
| 287 const size_t child_i = | 223 const size_t child_i = |
| 288 std::find(children.begin(), children.end(), node) - children.begin(); | 224 std::find(children.begin(), children.end(), node) - children.begin(); |
| 289 const size_t target_i = | 225 const size_t target_i = |
| 290 std::find(children.begin(), children.end(), relative_node) - | 226 std::find(children.begin(), children.end(), relative_node) - |
| 291 children.begin(); | 227 children.begin(); |
| 292 if ((direction == ORDER_DIRECTION_ABOVE && child_i == target_i + 1) || | 228 if ((direction == ORDER_DIRECTION_ABOVE && child_i == target_i + 1) || |
| 293 (direction == ORDER_DIRECTION_BELOW && child_i + 1 == target_i)) { | 229 (direction == ORDER_DIRECTION_BELOW && child_i + 1 == target_i)) { |
| 294 return false; | 230 return false; |
| 295 } | 231 } |
| 296 | 232 |
| 297 return true; | 233 return true; |
| 298 } | 234 } |
| 299 | 235 |
| 300 bool ViewManagerServiceImpl::CanDeleteNode(const NodeId& node_id) const { | |
| 301 return node_id.connection_id == id_; | |
| 302 } | |
| 303 | |
| 304 bool ViewManagerServiceImpl::CanDeleteView(const ViewId& view_id) const { | |
| 305 return view_id.connection_id == id_; | |
| 306 } | |
| 307 | |
| 308 bool ViewManagerServiceImpl::CanSetView(const Node* node, | |
| 309 const ViewId& view_id) const { | |
| 310 if (!node || !IsNodeDescendantOfRoots(node)) | |
| 311 return false; | |
| 312 | |
| 313 const View* view = GetView(view_id); | |
| 314 return (view && view_id.connection_id == id_) || view_id == ViewId(); | |
| 315 } | |
| 316 | |
| 317 bool ViewManagerServiceImpl::CanSetFocus(const Node* node) const { | |
| 318 // TODO(beng): security. | |
| 319 return true; | |
| 320 } | |
| 321 | |
| 322 bool ViewManagerServiceImpl::CanGetNodeTree(const Node* node) const { | |
| 323 if (!node) | |
| 324 return false; | |
| 325 | |
| 326 if (roots_.empty()) | |
| 327 return true; | |
| 328 | |
| 329 if (node->id().connection_id == id_) | |
| 330 return true; | |
| 331 | |
| 332 return roots_.count(NodeIdToTransportId(node->id())) > 0; | |
| 333 } | |
| 334 | |
| 335 bool ViewManagerServiceImpl::CanEmbed(Id transport_node_id) const { | |
| 336 const Node* node = GetNode(NodeIdFromTransportId(transport_node_id)); | |
| 337 return node && node->id().connection_id == id_; | |
| 338 } | |
| 339 | |
| 340 bool ViewManagerServiceImpl::CanSetNodeVisibility(const Node* node, | |
| 341 bool visibile) const { | |
| 342 return node && | |
| 343 (node->id().connection_id == id_ || | |
| 344 roots_.find(NodeIdToTransportId(node->id())) != roots_.end()) && | |
| 345 node->IsVisible() != visibile; | |
| 346 } | |
| 347 | |
| 348 bool ViewManagerServiceImpl::CanDescendIntoNodeForNodeTree( | |
| 349 const Node* node) const { | |
| 350 if (roots_.empty()) | |
| 351 return true; | |
| 352 | |
| 353 ViewManagerServiceImpl* connection = | |
| 354 root_node_manager_->GetConnectionWithRoot(node->id()); | |
| 355 return !connection || connection == this; | |
| 356 } | |
| 357 | |
| 358 bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source, | 236 bool ViewManagerServiceImpl::DeleteNodeImpl(ViewManagerServiceImpl* source, |
| 359 const NodeId& node_id) { | 237 Node* node) { |
| 360 DCHECK_EQ(node_id.connection_id, id_); | 238 DCHECK(node); |
| 361 Node* node = GetNode(node_id); | 239 DCHECK_EQ(node->id().connection_id, id_); |
| 362 if (!node) | |
| 363 return false; | |
| 364 RootNodeManager::ScopedChange change(source, root_node_manager_, true); | 240 RootNodeManager::ScopedChange change(source, root_node_manager_, true); |
| 365 delete node; | 241 delete node; |
| 366 return true; | 242 return true; |
| 367 } | 243 } |
| 368 | 244 |
| 369 bool ViewManagerServiceImpl::DeleteViewImpl(ViewManagerServiceImpl* source, | 245 bool ViewManagerServiceImpl::DeleteViewImpl(ViewManagerServiceImpl* source, |
| 370 const ViewId& view_id) { | 246 View* view) { |
| 371 DCHECK_EQ(view_id.connection_id, id_); | 247 DCHECK(view); |
| 372 View* view = GetView(view_id); | 248 DCHECK_EQ(view->id().connection_id, id_); |
| 373 if (!view) | |
| 374 return false; | |
| 375 RootNodeManager::ScopedChange change(source, root_node_manager_, false); | 249 RootNodeManager::ScopedChange change(source, root_node_manager_, false); |
| 376 if (view->node()) | 250 if (view->node()) |
| 377 view->node()->SetView(NULL); | 251 view->node()->SetView(NULL); |
| 378 view_map_.erase(view_id.view_id); | 252 view_map_.erase(view->id().view_id); |
| 379 // Make a copy of |view_id| as once we delete view |view_id| may no longer be | 253 const ViewId view_id(view->id()); |
| 380 // valid. | |
| 381 const ViewId view_id_copy(view_id); | |
| 382 delete view; | 254 delete view; |
| 383 root_node_manager_->ProcessViewDeleted(view_id_copy); | 255 root_node_manager_->ProcessViewDeleted(view_id); |
| 384 return true; | 256 return true; |
| 385 } | 257 } |
| 386 | 258 |
| 387 bool ViewManagerServiceImpl::SetViewImpl(Node* node, const ViewId& view_id) { | 259 bool ViewManagerServiceImpl::SetViewImpl(Node* node, View* view) { |
| 388 DCHECK(node); // CanSetView() should have verified node exists. | 260 DCHECK(node); // CanSetView() should have verified node exists. |
| 389 View* view = GetView(view_id); | |
| 390 RootNodeManager::ScopedChange change(this, root_node_manager_, false); | 261 RootNodeManager::ScopedChange change(this, root_node_manager_, false); |
| 391 node->SetView(view); | 262 node->SetView(view); |
| 392 return true; | 263 return true; |
| 393 } | 264 } |
| 394 | 265 |
| 395 void ViewManagerServiceImpl::GetUnknownNodesFrom( | 266 void ViewManagerServiceImpl::GetUnknownNodesFrom( |
| 396 const Node* node, | 267 const Node* node, |
| 397 std::vector<const Node*>* nodes) { | 268 std::vector<const Node*>* nodes) { |
| 398 const Id transport_id = NodeIdToTransportId(node->id()); | 269 if (IsNodeKnown(node)) |
| 399 if (known_nodes_.count(transport_id) == 1) | |
| 400 return; | 270 return; |
| 401 nodes->push_back(node); | 271 nodes->push_back(node); |
| 402 known_nodes_.insert(transport_id); | 272 known_nodes_.insert(NodeIdToTransportId(node->id())); |
| 403 std::vector<const Node*> children(node->GetChildren()); | 273 std::vector<const Node*> children(node->GetChildren()); |
| 404 for (size_t i = 0 ; i < children.size(); ++i) | 274 for (size_t i = 0 ; i < children.size(); ++i) |
| 405 GetUnknownNodesFrom(children[i], nodes); | 275 GetUnknownNodesFrom(children[i], nodes); |
| 406 } | 276 } |
| 407 | 277 |
| 408 void ViewManagerServiceImpl::RemoveFromKnown(const Node* node, | 278 void ViewManagerServiceImpl::RemoveFromKnown(const Node* node, |
| 409 std::vector<Node*>* local_nodes) { | 279 std::vector<Node*>* local_nodes) { |
| 410 if (node->id().connection_id == id_) { | 280 if (node->id().connection_id == id_) { |
| 411 if (local_nodes) | 281 if (local_nodes) |
| 412 local_nodes->push_back(GetNode(node->id())); | 282 local_nodes->push_back(GetNode(node->id())); |
| 413 return; | 283 return; |
| 414 } | 284 } |
| 415 known_nodes_.erase(NodeIdToTransportId(node->id())); | 285 known_nodes_.erase(NodeIdToTransportId(node->id())); |
| 416 std::vector<const Node*> children = node->GetChildren(); | 286 std::vector<const Node*> children = node->GetChildren(); |
| 417 for (size_t i = 0; i < children.size(); ++i) | 287 for (size_t i = 0; i < children.size(); ++i) |
| 418 RemoveFromKnown(children[i], local_nodes); | 288 RemoveFromKnown(children[i], local_nodes); |
| 419 } | 289 } |
| 420 | 290 |
| 421 bool ViewManagerServiceImpl::IsNodeEmbeddedInAnotherConnection( | |
| 422 const Node* node) const { | |
| 423 while (node) { | |
| 424 const ViewManagerServiceImpl* connection = | |
| 425 root_node_manager_->GetConnectionWithRoot(node->id()); | |
| 426 if (connection) | |
| 427 return connection != this; | |
| 428 node = node->GetParent(); | |
| 429 } | |
| 430 return false; | |
| 431 } | |
| 432 | |
| 433 void ViewManagerServiceImpl::AddRoot(const NodeId& node_id) { | 291 void ViewManagerServiceImpl::AddRoot(const NodeId& node_id) { |
| 434 const Id transport_node_id(NodeIdToTransportId(node_id)); | 292 const Id transport_node_id(NodeIdToTransportId(node_id)); |
| 435 CHECK(roots_.count(transport_node_id) == 0); | 293 CHECK(roots_.count(transport_node_id) == 0); |
| 436 | 294 |
| 437 std::vector<const Node*> to_send; | 295 std::vector<const Node*> to_send; |
| 438 CHECK_EQ(creator_id_, node_id.connection_id); | 296 CHECK_EQ(creator_id_, node_id.connection_id); |
| 439 roots_.insert(transport_node_id); | 297 roots_.insert(transport_node_id); |
| 440 Node* node = GetNode(node_id); | 298 Node* node = GetNode(node_id); |
| 441 CHECK(node); | 299 CHECK(node); |
| 442 if (known_nodes_.count(transport_node_id) == 0) { | 300 if (!IsNodeKnown(node)) { |
| 443 GetUnknownNodesFrom(node, &to_send); | 301 GetUnknownNodesFrom(node, &to_send); |
| 444 } else { | 302 } else { |
| 445 // Even though the connection knows about the new root we need to tell it | 303 // Even though the connection knows about the new root we need to tell it |
| 446 // |node| is now a root. | 304 // |node| is now a root. |
| 447 to_send.push_back(node); | 305 to_send.push_back(node); |
| 448 } | 306 } |
| 449 | 307 |
| 450 client()->OnRootAdded(NodesToNodeDatas(to_send)); | 308 client()->OnRootAdded(NodesToNodeDatas(to_send)); |
| 451 root_node_manager_->OnConnectionMessagedClient(id_); | 309 root_node_manager_->OnConnectionMessagedClient(id_); |
| 452 } | 310 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 481 return; | 339 return; |
| 482 | 340 |
| 483 Node* node = GetNode(node_id); | 341 Node* node = GetNode(node_id); |
| 484 CHECK(node); | 342 CHECK(node); |
| 485 CHECK(node->id().connection_id == node_id.connection_id); | 343 CHECK(node->id().connection_id == node_id.connection_id); |
| 486 std::vector<Node*> children = node->GetChildren(); | 344 std::vector<Node*> children = node->GetChildren(); |
| 487 for (size_t i = 0; i < children.size(); ++i) | 345 for (size_t i = 0; i < children.size(); ++i) |
| 488 node->Remove(children[i]); | 346 node->Remove(children[i]); |
| 489 } | 347 } |
| 490 | 348 |
| 491 bool ViewManagerServiceImpl::IsNodeDescendantOfRoots(const Node* node) const { | |
| 492 if (roots_.empty()) | |
| 493 return true; | |
| 494 if (!node) | |
| 495 return false; | |
| 496 const Id invalid_node_id = NodeIdToTransportId(InvalidNodeId()); | |
| 497 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) { | |
| 498 if (*i == invalid_node_id) | |
| 499 continue; | |
| 500 const Node* root = GetNode(NodeIdFromTransportId(*i)); | |
| 501 DCHECK(root); | |
| 502 if (root->Contains(node)) | |
| 503 return true; | |
| 504 } | |
| 505 return false; | |
| 506 } | |
| 507 | |
| 508 bool ViewManagerServiceImpl::ShouldNotifyOnHierarchyChange( | |
| 509 const Node* node, | |
| 510 const Node** new_parent, | |
| 511 const Node** old_parent, | |
| 512 std::vector<const Node*>* to_send) { | |
| 513 // If the node is not in |roots_| or was never known to this connection then | |
| 514 // don't notify the client about it. | |
| 515 if (node->id().connection_id != id_ && | |
| 516 known_nodes_.count(NodeIdToTransportId(node->id())) == 0 && | |
| 517 !IsNodeDescendantOfRoots(node)) { | |
| 518 return false; | |
| 519 } | |
| 520 if (!IsNodeDescendantOfRoots(*new_parent)) | |
| 521 *new_parent = NULL; | |
| 522 if (!IsNodeDescendantOfRoots(*old_parent)) | |
| 523 *old_parent = NULL; | |
| 524 | |
| 525 if (*new_parent) { | |
| 526 // On getting a new parent we may need to communicate new nodes to the | |
| 527 // client. We do that in the following cases: | |
| 528 // . New parent is a descendant of the roots. In this case the client | |
| 529 // already knows all ancestors, so we only have to communicate descendants | |
| 530 // of node the client doesn't know about. | |
| 531 // . If the client knew about the parent, we have to do the same. | |
| 532 // . If the client knows about the node and is added to a tree the client | |
| 533 // doesn't know about we have to communicate from the root down (the | |
| 534 // client is learning about a new root). | |
| 535 if (root_node_manager_->root()->Contains(*new_parent) || | |
| 536 known_nodes_.count(NodeIdToTransportId((*new_parent)->id()))) { | |
| 537 GetUnknownNodesFrom(node, to_send); | |
| 538 return true; | |
| 539 } | |
| 540 // If parent wasn't known we have to communicate from the root down. | |
| 541 if (known_nodes_.count(NodeIdToTransportId(node->id()))) { | |
| 542 // No need to check against |roots_| as client should always know it's | |
| 543 // |roots_|. | |
| 544 GetUnknownNodesFrom((*new_parent)->GetRoot(), to_send); | |
| 545 return true; | |
| 546 } | |
| 547 } | |
| 548 // Otherwise only communicate the change if the node was known. We shouldn't | |
| 549 // need to communicate any nodes on a remove. | |
| 550 return known_nodes_.count(NodeIdToTransportId(node->id())) > 0; | |
| 551 } | |
| 552 | |
| 553 Array<NodeDataPtr> ViewManagerServiceImpl::NodesToNodeDatas( | 349 Array<NodeDataPtr> ViewManagerServiceImpl::NodesToNodeDatas( |
| 554 const std::vector<const Node*>& nodes) { | 350 const std::vector<const Node*>& nodes) { |
| 555 Array<NodeDataPtr> array(nodes.size()); | 351 Array<NodeDataPtr> array(nodes.size()); |
| 556 for (size_t i = 0; i < nodes.size(); ++i) { | 352 for (size_t i = 0; i < nodes.size(); ++i) { |
| 557 const Node* node = nodes[i]; | 353 const Node* node = nodes[i]; |
| 558 DCHECK(known_nodes_.count(NodeIdToTransportId(node->id())) > 0); | 354 DCHECK(IsNodeKnown(node)); |
| 559 const Node* parent = node->GetParent(); | 355 const Node* parent = node->GetParent(); |
| 560 // If the parent isn't known, it means the parent is not visible to us (not | 356 // If the parent isn't known, it means the parent is not visible to us (not |
| 561 // in roots), and should not be sent over. | 357 // in roots), and should not be sent over. |
| 562 if (parent && known_nodes_.count(NodeIdToTransportId(parent->id())) == 0) | 358 if (parent && !IsNodeKnown(parent)) |
| 563 parent = NULL; | 359 parent = NULL; |
| 564 NodeDataPtr inode(NodeData::New()); | 360 NodeDataPtr inode(NodeData::New()); |
| 565 inode->parent_id = NodeIdToTransportId(parent ? parent->id() : NodeId()); | 361 inode->parent_id = NodeIdToTransportId(parent ? parent->id() : NodeId()); |
| 566 inode->node_id = NodeIdToTransportId(node->id()); | 362 inode->node_id = NodeIdToTransportId(node->id()); |
| 363 // TODO(sky): should the id only be sent if known? |
| 567 inode->view_id = | 364 inode->view_id = |
| 568 ViewIdToTransportId(node->view() ? node->view()->id() : ViewId()); | 365 ViewIdToTransportId(node->view() ? node->view()->id() : ViewId()); |
| 569 inode->bounds = Rect::From(node->bounds()); | 366 inode->bounds = Rect::From(node->bounds()); |
| 570 array[i] = inode.Pass(); | 367 array[i] = inode.Pass(); |
| 571 } | 368 } |
| 572 return array.Pass(); | 369 return array.Pass(); |
| 573 } | 370 } |
| 574 | 371 |
| 575 void ViewManagerServiceImpl::GetNodeTreeImpl( | 372 void ViewManagerServiceImpl::GetNodeTreeImpl( |
| 576 const Node* node, | 373 const Node* node, |
| 577 std::vector<const Node*>* nodes) const { | 374 std::vector<const Node*>* nodes) const { |
| 578 DCHECK(node); | 375 DCHECK(node); |
| 579 | 376 |
| 580 if (!CanGetNodeTree(node)) | 377 if (!access_policy_->CanGetNodeTree(node)) |
| 581 return; | 378 return; |
| 582 | 379 |
| 583 nodes->push_back(node); | 380 nodes->push_back(node); |
| 584 | 381 |
| 585 if (!CanDescendIntoNodeForNodeTree(node)) | 382 if (!access_policy_->CanDescendIntoNodeForNodeTree(node)) |
| 586 return; | 383 return; |
| 587 | 384 |
| 588 std::vector<const Node*> children(node->GetChildren()); | 385 std::vector<const Node*> children(node->GetChildren()); |
| 589 for (size_t i = 0 ; i < children.size(); ++i) | 386 for (size_t i = 0 ; i < children.size(); ++i) |
| 590 GetNodeTreeImpl(children[i], nodes); | 387 GetNodeTreeImpl(children[i], nodes); |
| 591 } | 388 } |
| 592 | 389 |
| 593 void ViewManagerServiceImpl::CreateNode( | 390 void ViewManagerServiceImpl::CreateNode( |
| 594 Id transport_node_id, | 391 Id transport_node_id, |
| 595 const Callback<void(ErrorCode)>& callback) { | 392 const Callback<void(ErrorCode)>& callback) { |
| 596 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | 393 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); |
| 597 ErrorCode error_code = ERROR_CODE_NONE; | 394 ErrorCode error_code = ERROR_CODE_NONE; |
| 598 if (node_id.connection_id != id_) { | 395 if (node_id.connection_id != id_) { |
| 599 error_code = ERROR_CODE_ILLEGAL_ARGUMENT; | 396 error_code = ERROR_CODE_ILLEGAL_ARGUMENT; |
| 600 } else if (node_map_.find(node_id.node_id) != node_map_.end()) { | 397 } else if (node_map_.find(node_id.node_id) != node_map_.end()) { |
| 601 error_code = ERROR_CODE_VALUE_IN_USE; | 398 error_code = ERROR_CODE_VALUE_IN_USE; |
| 602 } else { | 399 } else { |
| 603 node_map_[node_id.node_id] = new Node(root_node_manager_, node_id); | 400 node_map_[node_id.node_id] = new Node(root_node_manager_, node_id); |
| 604 known_nodes_.insert(transport_node_id); | 401 known_nodes_.insert(transport_node_id); |
| 605 } | 402 } |
| 606 callback.Run(error_code); | 403 callback.Run(error_code); |
| 607 } | 404 } |
| 608 | 405 |
| 609 void ViewManagerServiceImpl::DeleteNode( | 406 void ViewManagerServiceImpl::DeleteNode( |
| 610 Id transport_node_id, | 407 Id transport_node_id, |
| 611 const Callback<void(bool)>& callback) { | 408 const Callback<void(bool)>& callback) { |
| 612 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | 409 Node* node = GetNode(NodeIdFromTransportId(transport_node_id)); |
| 613 bool success = false; | 410 bool success = false; |
| 614 if (CanDeleteNode(node_id)) { | 411 if (node && access_policy_->CanDeleteNode(node)) { |
| 615 ViewManagerServiceImpl* connection = root_node_manager_->GetConnection( | 412 ViewManagerServiceImpl* connection = root_node_manager_->GetConnection( |
| 616 node_id.connection_id); | 413 node->id().connection_id); |
| 617 success = connection && connection->DeleteNodeImpl(this, node_id); | 414 success = connection && connection->DeleteNodeImpl(this, node); |
| 618 } | 415 } |
| 619 callback.Run(success); | 416 callback.Run(success); |
| 620 } | 417 } |
| 621 | 418 |
| 622 void ViewManagerServiceImpl::AddNode( | 419 void ViewManagerServiceImpl::AddNode( |
| 623 Id parent_id, | 420 Id parent_id, |
| 624 Id child_id, | 421 Id child_id, |
| 625 const Callback<void(bool)>& callback) { | 422 const Callback<void(bool)>& callback) { |
| 626 bool success = false; | 423 bool success = false; |
| 627 Node* parent = GetNode(NodeIdFromTransportId(parent_id)); | 424 Node* parent = GetNode(NodeIdFromTransportId(parent_id)); |
| 628 Node* child = GetNode(NodeIdFromTransportId(child_id)); | 425 Node* child = GetNode(NodeIdFromTransportId(child_id)); |
| 629 if (CanAddNode(parent, child)) { | 426 if (parent && child && child->GetParent() != parent && |
| 427 !child->Contains(parent) && access_policy_->CanAddNode(parent, child)) { |
| 630 success = true; | 428 success = true; |
| 631 RootNodeManager::ScopedChange change(this, root_node_manager_, false); | 429 RootNodeManager::ScopedChange change(this, root_node_manager_, false); |
| 632 parent->Add(child); | 430 parent->Add(child); |
| 633 } | 431 } |
| 634 callback.Run(success); | 432 callback.Run(success); |
| 635 } | 433 } |
| 636 | 434 |
| 637 void ViewManagerServiceImpl::RemoveNodeFromParent( | 435 void ViewManagerServiceImpl::RemoveNodeFromParent( |
| 638 Id node_id, | 436 Id node_id, |
| 639 const Callback<void(bool)>& callback) { | 437 const Callback<void(bool)>& callback) { |
| 640 bool success = false; | 438 bool success = false; |
| 641 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 439 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
| 642 if (CanRemoveNodeFromParent(node)) { | 440 if (node && node->GetParent() && |
| 441 access_policy_->CanRemoveNodeFromParent(node)) { |
| 643 success = true; | 442 success = true; |
| 644 RootNodeManager::ScopedChange change(this, root_node_manager_, false); | 443 RootNodeManager::ScopedChange change(this, root_node_manager_, false); |
| 645 node->GetParent()->Remove(node); | 444 node->GetParent()->Remove(node); |
| 646 } | 445 } |
| 647 callback.Run(success); | 446 callback.Run(success); |
| 648 } | 447 } |
| 649 | 448 |
| 650 void ViewManagerServiceImpl::ReorderNode(Id node_id, | 449 void ViewManagerServiceImpl::ReorderNode(Id node_id, |
| 651 Id relative_node_id, | 450 Id relative_node_id, |
| 652 OrderDirection direction, | 451 OrderDirection direction, |
| 653 const Callback<void(bool)>& callback) { | 452 const Callback<void(bool)>& callback) { |
| 654 bool success = false; | 453 bool success = false; |
| 655 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 454 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
| 656 Node* relative_node = GetNode(NodeIdFromTransportId(relative_node_id)); | 455 Node* relative_node = GetNode(NodeIdFromTransportId(relative_node_id)); |
| 657 if (CanReorderNode(node, relative_node, direction)) { | 456 if (CanReorderNode(node, relative_node, direction)) { |
| 658 success = true; | 457 success = true; |
| 659 RootNodeManager::ScopedChange change(this, root_node_manager_, false); | 458 RootNodeManager::ScopedChange change(this, root_node_manager_, false); |
| 660 node->GetParent()->Reorder(node, relative_node, direction); | 459 node->GetParent()->Reorder(node, relative_node, direction); |
| 661 root_node_manager_->ProcessNodeReorder(node, relative_node, direction); | 460 root_node_manager_->ProcessNodeReorder(node, relative_node, direction); |
| 662 } | 461 } |
| 663 callback.Run(success); | 462 callback.Run(success); |
| 664 } | 463 } |
| 665 | 464 |
| 666 void ViewManagerServiceImpl::GetNodeTree( | 465 void ViewManagerServiceImpl::GetNodeTree( |
| 667 Id node_id, | 466 Id node_id, |
| 668 const Callback<void(Array<NodeDataPtr>)>& callback) { | 467 const Callback<void(Array<NodeDataPtr>)>& callback) { |
| 669 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 468 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
| 670 std::vector<const Node*> nodes; | 469 std::vector<const Node*> nodes; |
| 671 if (CanGetNodeTree(node)) { | 470 if (node) { |
| 672 GetNodeTreeImpl(node, &nodes); | 471 GetNodeTreeImpl(node, &nodes); |
| 673 #if !defined(NDEBUG) | 472 // TODO(sky): this should map in nodes that weren't none. |
| 674 for (size_t i = 0; i < nodes.size(); ++i) | |
| 675 DCHECK_GT(known_nodes_.count(NodeIdToTransportId(nodes[i]->id())), 0u); | |
| 676 #endif | |
| 677 } | 473 } |
| 678 callback.Run(NodesToNodeDatas(nodes)); | 474 callback.Run(NodesToNodeDatas(nodes)); |
| 679 } | 475 } |
| 680 | 476 |
| 681 void ViewManagerServiceImpl::CreateView( | 477 void ViewManagerServiceImpl::CreateView( |
| 682 Id transport_view_id, | 478 Id transport_view_id, |
| 683 const Callback<void(bool)>& callback) { | 479 const Callback<void(bool)>& callback) { |
| 684 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); | 480 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); |
| 685 if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) { | 481 if (view_id.connection_id != id_ || view_map_.count(view_id.view_id)) { |
| 686 callback.Run(false); | 482 callback.Run(false); |
| 687 return; | 483 return; |
| 688 } | 484 } |
| 689 view_map_[view_id.view_id] = new View(view_id); | 485 view_map_[view_id.view_id] = new View(view_id); |
| 690 callback.Run(true); | 486 callback.Run(true); |
| 691 } | 487 } |
| 692 | 488 |
| 693 void ViewManagerServiceImpl::DeleteView( | 489 void ViewManagerServiceImpl::DeleteView(Id transport_view_id, |
| 694 Id transport_view_id, | 490 const Callback<void(bool)>& callback) { |
| 695 const Callback<void(bool)>& callback) { | 491 View* view = GetView(ViewIdFromTransportId(transport_view_id)); |
| 696 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); | 492 bool did_delete = false; |
| 697 bool did_delete = CanDeleteView(view_id); | 493 if (view && access_policy_->CanDeleteView(view)) { |
| 698 if (did_delete) { | |
| 699 ViewManagerServiceImpl* connection = root_node_manager_->GetConnection( | 494 ViewManagerServiceImpl* connection = root_node_manager_->GetConnection( |
| 700 view_id.connection_id); | 495 view->id().connection_id); |
| 701 did_delete = (connection && connection->DeleteViewImpl(this, view_id)); | 496 did_delete = (connection && connection->DeleteViewImpl(this, view)); |
| 702 } | 497 } |
| 703 callback.Run(did_delete); | 498 callback.Run(did_delete); |
| 704 } | 499 } |
| 705 | 500 |
| 706 void ViewManagerServiceImpl::SetView(Id transport_node_id, | 501 void ViewManagerServiceImpl::SetView(Id transport_node_id, |
| 707 Id transport_view_id, | 502 Id transport_view_id, |
| 708 const Callback<void(bool)>& callback) { | 503 const Callback<void(bool)>& callback) { |
| 709 Node* node = GetNode(NodeIdFromTransportId(transport_node_id)); | 504 Node* node = GetNode(NodeIdFromTransportId(transport_node_id)); |
| 710 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); | 505 View* view = GetView(ViewIdFromTransportId(transport_view_id)); |
| 711 callback.Run(CanSetView(node, view_id) && SetViewImpl(node, view_id)); | 506 const bool valid_view = view || |
| 507 ViewIdFromTransportId(transport_node_id) != ViewId(); |
| 508 callback.Run(valid_view && node && access_policy_->CanSetView(node, view) && |
| 509 SetViewImpl(node, view)); |
| 712 } | 510 } |
| 713 | 511 |
| 714 void ViewManagerServiceImpl::SetViewContents( | 512 void ViewManagerServiceImpl::SetViewContents( |
| 715 Id view_id, | 513 Id view_id, |
| 716 ScopedSharedBufferHandle buffer, | 514 ScopedSharedBufferHandle buffer, |
| 717 uint32_t buffer_size, | 515 uint32_t buffer_size, |
| 718 const Callback<void(bool)>& callback) { | 516 const Callback<void(bool)>& callback) { |
| 517 // TODO(sky): add coverage of not being able to set for random view. |
| 719 View* view = GetView(ViewIdFromTransportId(view_id)); | 518 View* view = GetView(ViewIdFromTransportId(view_id)); |
| 720 if (!view) { | 519 if (!view || !access_policy_->CanSetViewContents(view)) { |
| 721 callback.Run(false); | 520 callback.Run(false); |
| 722 return; | 521 return; |
| 723 } | 522 } |
| 724 void* handle_data; | 523 void* handle_data; |
| 725 if (MapBuffer(buffer.get(), 0, buffer_size, &handle_data, | 524 if (MapBuffer(buffer.get(), 0, buffer_size, &handle_data, |
| 726 MOJO_MAP_BUFFER_FLAG_NONE) != MOJO_RESULT_OK) { | 525 MOJO_MAP_BUFFER_FLAG_NONE) != MOJO_RESULT_OK) { |
| 727 callback.Run(false); | 526 callback.Run(false); |
| 728 return; | 527 return; |
| 729 } | 528 } |
| 730 SkBitmap bitmap; | 529 SkBitmap bitmap; |
| 731 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(handle_data), | 530 gfx::PNGCodec::Decode(static_cast<const unsigned char*>(handle_data), |
| 732 buffer_size, &bitmap); | 531 buffer_size, &bitmap); |
| 733 view->SetBitmap(bitmap); | 532 view->SetBitmap(bitmap); |
| 734 UnmapBuffer(handle_data); | 533 UnmapBuffer(handle_data); |
| 735 callback.Run(true); | 534 callback.Run(true); |
| 736 } | 535 } |
| 737 | 536 |
| 738 void ViewManagerServiceImpl::SetFocus(Id node_id, | 537 void ViewManagerServiceImpl::SetFocus(Id node_id, |
| 739 const Callback<void(bool)> & callback) { | 538 const Callback<void(bool)> & callback) { |
| 740 bool success = false; | 539 bool success = false; |
| 741 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 540 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
| 742 if (CanSetFocus(node)) { | 541 if (node && access_policy_->CanSetFocus(node)) { |
| 743 success = true; | 542 success = true; |
| 744 node->window()->Focus(); | 543 node->window()->Focus(); |
| 745 } | 544 } |
| 746 callback.Run(success); | 545 callback.Run(success); |
| 747 } | 546 } |
| 748 | 547 |
| 749 void ViewManagerServiceImpl::SetNodeBounds( | 548 void ViewManagerServiceImpl::SetNodeBounds( |
| 750 Id node_id, | 549 Id node_id, |
| 751 RectPtr bounds, | 550 RectPtr bounds, |
| 752 const Callback<void(bool)>& callback) { | 551 const Callback<void(bool)>& callback) { |
| 753 if (NodeIdFromTransportId(node_id).connection_id != id_) { | 552 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
| 754 callback.Run(false); | 553 const bool success = node && access_policy_->CanSetNodeBounds(node); |
| 755 return; | 554 if (success) { |
| 555 RootNodeManager::ScopedChange change(this, root_node_manager_, false); |
| 556 gfx::Rect old_bounds = node->window()->bounds(); |
| 557 node->window()->SetBounds(bounds.To<gfx::Rect>()); |
| 756 } | 558 } |
| 757 | 559 callback.Run(success); |
| 758 Node* node = GetNode(NodeIdFromTransportId(node_id)); | |
| 759 if (!node) { | |
| 760 callback.Run(false); | |
| 761 return; | |
| 762 } | |
| 763 | |
| 764 RootNodeManager::ScopedChange change(this, root_node_manager_, false); | |
| 765 gfx::Rect old_bounds = node->window()->bounds(); | |
| 766 node->window()->SetBounds(bounds.To<gfx::Rect>()); | |
| 767 callback.Run(true); | |
| 768 } | 560 } |
| 769 | 561 |
| 770 void ViewManagerServiceImpl::SetNodeVisibility( | 562 void ViewManagerServiceImpl::SetNodeVisibility( |
| 771 Id transport_node_id, | 563 Id transport_node_id, |
| 772 bool visible, | 564 bool visible, |
| 773 const Callback<void(bool)>& callback) { | 565 const Callback<void(bool)>& callback) { |
| 774 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | 566 Node* node = GetNode(NodeIdFromTransportId(transport_node_id)); |
| 775 Node* node = GetNode(node_id); | 567 const bool success = node && node->IsVisible() != visible && |
| 776 const bool success = CanSetNodeVisibility(node, visible); | 568 access_policy_->CanChangeNodeVisibility(node); |
| 777 if (success) { | 569 if (success) { |
| 778 DCHECK(node); | 570 DCHECK(node); |
| 779 node->SetVisible(visible); | 571 node->SetVisible(visible); |
| 780 } | 572 } |
| 781 // TODO(sky): need to notify of visibility changes. | 573 // TODO(sky): need to notify of visibility changes. |
| 782 callback.Run(success); | 574 callback.Run(success); |
| 783 } | 575 } |
| 784 | 576 |
| 785 void ViewManagerServiceImpl::Embed(const String& url, | 577 void ViewManagerServiceImpl::Embed(const String& url, |
| 786 Id transport_node_id, | 578 Id transport_node_id, |
| 787 const Callback<void(bool)>& callback) { | 579 const Callback<void(bool)>& callback) { |
| 788 if (NodeIdFromTransportId(transport_node_id) == InvalidNodeId()) { | 580 if (NodeIdFromTransportId(transport_node_id) == InvalidNodeId()) { |
| 789 root_node_manager_->EmbedRoot(url); | 581 root_node_manager_->EmbedRoot(url); |
| 790 callback.Run(true); | 582 callback.Run(true); |
| 791 return; | 583 return; |
| 792 } | 584 } |
| 793 bool success = CanEmbed(transport_node_id); | 585 const Node* node = GetNode(NodeIdFromTransportId(transport_node_id)); |
| 586 bool success = node && access_policy_->CanEmbed(node); |
| 794 if (success) { | 587 if (success) { |
| 795 // Only allow a node to be the root for one connection. | 588 // Only allow a node to be the root for one connection. |
| 796 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | 589 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); |
| 797 ViewManagerServiceImpl* connection_by_url = | 590 ViewManagerServiceImpl* connection_by_url = |
| 798 root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>()); | 591 root_node_manager_->GetConnectionByCreator(id_, url.To<std::string>()); |
| 799 ViewManagerServiceImpl* connection_with_node_as_root = | 592 ViewManagerServiceImpl* connection_with_node_as_root = |
| 800 root_node_manager_->GetConnectionWithRoot(node_id); | 593 root_node_manager_->GetConnectionWithRoot(node_id); |
| 801 if ((connection_by_url != connection_with_node_as_root || | 594 if ((connection_by_url != connection_with_node_as_root || |
| 802 (!connection_by_url && !connection_with_node_as_root)) && | 595 (!connection_by_url && !connection_with_node_as_root)) && |
| 803 (!connection_by_url || !connection_by_url->HasRoot(node_id))) { | 596 (!connection_by_url || !connection_by_url->HasRoot(node_id))) { |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 846 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) | 639 for (NodeIdSet::const_iterator i = roots_.begin(); i != roots_.end(); ++i) |
| 847 GetUnknownNodesFrom(GetNode(NodeIdFromTransportId(*i)), &to_send); | 640 GetUnknownNodesFrom(GetNode(NodeIdFromTransportId(*i)), &to_send); |
| 848 } | 641 } |
| 849 | 642 |
| 850 client()->OnViewManagerConnectionEstablished( | 643 client()->OnViewManagerConnectionEstablished( |
| 851 id_, | 644 id_, |
| 852 creator_url_, | 645 creator_url_, |
| 853 NodesToNodeDatas(to_send)); | 646 NodesToNodeDatas(to_send)); |
| 854 } | 647 } |
| 855 | 648 |
| 649 const base::hash_set<Id>& |
| 650 ViewManagerServiceImpl::GetRootsForAccessPolicy() const { |
| 651 return roots_; |
| 652 } |
| 653 |
| 654 bool ViewManagerServiceImpl::IsNodeKnownForAccessPolicy( |
| 655 const Node* node) const { |
| 656 return IsNodeKnown(node); |
| 657 } |
| 658 |
| 659 bool ViewManagerServiceImpl::IsNodeRootOfAnotherConnectionForAccessPolicy( |
| 660 const Node* node) const { |
| 661 ViewManagerServiceImpl* connection = |
| 662 root_node_manager_->GetConnectionWithRoot(node->id()); |
| 663 return connection && connection != this; |
| 664 } |
| 665 |
| 856 } // namespace service | 666 } // namespace service |
| 857 } // namespace mojo | 667 } // namespace mojo |
| OLD | NEW |