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: change this! | |
Ben Goodger (Google)
2014/07/25 20:51:46
You can now go ahead and cite http://crbug.com/397
sky
2014/07/25 21:10:46
Done.
| |
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 | |
655 ViewManagerServiceImpl::IsNodeKnownForAccessPolicy(const Node* node) const { | |
656 return IsNodeKnown(node); | |
657 } | |
658 | |
659 bool ViewManagerServiceImpl::IsNodeEmbeddedInAnotherConnectionForAccessPolicy( | |
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 |