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/public/cpp/view_manager/lib/view_manager_synchronizer.h" | 5 #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/run_loop.h" | 9 #include "base/run_loop.h" |
10 #include "mojo/public/cpp/bindings/allocation_scope.h" | 10 #include "mojo/public/cpp/bindings/allocation_scope.h" |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 | 178 |
179 DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction); | 179 DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction); |
180 }; | 180 }; |
181 | 181 |
182 ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager) | 182 ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager) |
183 : view_manager_(view_manager), | 183 : view_manager_(view_manager), |
184 connected_(false), | 184 connected_(false), |
185 connection_id_(0), | 185 connection_id_(0), |
186 next_id_(1), | 186 next_id_(1), |
187 next_change_id_(0), | 187 next_change_id_(0), |
| 188 sync_factory_(this), |
188 init_loop_(NULL) { | 189 init_loop_(NULL) { |
189 InterfacePipe<services::view_manager::IViewManager, AnyInterface> | 190 InterfacePipe<services::view_manager::IViewManager, AnyInterface> |
190 view_manager_pipe; | 191 view_manager_pipe; |
191 AllocationScope scope; | 192 AllocationScope scope; |
192 MessagePipeHandle client_handle = view_manager_pipe.handle_to_peer.get(); | 193 MessagePipeHandle client_handle = view_manager_pipe.handle_to_peer.get(); |
193 ViewManagerPrivate(view_manager_).shell()->Connect( | 194 ViewManagerPrivate(view_manager_).shell()->Connect( |
194 "mojo:mojo_view_manager", view_manager_pipe.handle_to_peer.Pass()); | 195 "mojo:mojo_view_manager", view_manager_pipe.handle_to_peer.Pass()); |
195 service_.reset(view_manager_pipe.handle_to_self.Pass(), this); | 196 service_.reset(view_manager_pipe.handle_to_self.Pass(), this); |
196 service_->GetNodeTree( | 197 service_->GetNodeTree( |
197 1, | 198 1, |
198 base::Bind(&ViewManagerSynchronizer::OnRootTreeReceived, | 199 base::Bind(&ViewManagerSynchronizer::OnRootTreeReceived, |
199 base::Unretained(this))); | 200 base::Unretained(this))); |
200 base::RunLoop loop; | 201 base::RunLoop loop; |
201 init_loop_ = &loop; | 202 init_loop_ = &loop; |
202 init_loop_->Run(); | 203 init_loop_->Run(); |
203 init_loop_ = NULL; | 204 init_loop_ = NULL; |
204 } | 205 } |
205 | 206 |
206 ViewManagerSynchronizer::~ViewManagerSynchronizer() { | 207 ViewManagerSynchronizer::~ViewManagerSynchronizer() { |
| 208 DoSync(); |
207 } | 209 } |
208 | 210 |
209 TransportNodeId ViewManagerSynchronizer::CreateViewTreeNode() { | 211 TransportNodeId ViewManagerSynchronizer::CreateViewTreeNode() { |
210 DCHECK(connected_); | 212 DCHECK(connected_); |
211 uint16_t id = ++next_id_; | 213 uint16_t id = ++next_id_; |
212 pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this)); | 214 pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this)); |
213 ScheduleSync(); | 215 ScheduleSync(); |
214 return MakeTransportNodeId(connection_id_, id); | 216 return MakeTransportNodeId(connection_id_, id); |
215 } | 217 } |
216 | 218 |
(...skipping 19 matching lines...) Expand all Loading... |
236 TransportNodeId parent_id) { | 238 TransportNodeId parent_id) { |
237 DCHECK(connected_); | 239 DCHECK(connected_); |
238 pending_transactions_.push_back( | 240 pending_transactions_.push_back( |
239 new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE, | 241 new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE, |
240 child_id, | 242 child_id, |
241 parent_id, | 243 parent_id, |
242 this)); | 244 this)); |
243 ScheduleSync(); | 245 ScheduleSync(); |
244 } | 246 } |
245 | 247 |
| 248 bool ViewManagerSynchronizer::OwnsNode(TransportNodeId id) const { |
| 249 return HiWord(id) == connection_id_; |
| 250 } |
| 251 |
246 //////////////////////////////////////////////////////////////////////////////// | 252 //////////////////////////////////////////////////////////////////////////////// |
247 // ViewManagerSynchronizer, IViewManagerClient implementation: | 253 // ViewManagerSynchronizer, IViewManagerClient implementation: |
248 | 254 |
249 void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) { | 255 void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) { |
250 connected_ = true; | 256 connected_ = true; |
251 connection_id_ = connection_id; | 257 connection_id_ = connection_id; |
252 ScheduleSync(); | 258 ScheduleSync(); |
253 } | 259 } |
254 | 260 |
255 void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node_id, | 261 void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node_id, |
256 uint32_t new_parent_id, | 262 uint32_t new_parent_id, |
257 uint32_t old_parent_id, | 263 uint32_t old_parent_id, |
258 uint32_t change_id) { | 264 uint32_t change_id) { |
259 if (change_id == 0) { | 265 if (change_id == 0) { |
260 ViewTreeNode* new_parent = | 266 ViewTreeNode* new_parent = view_manager_->GetNodeById(new_parent_id); |
261 view_manager_->tree()->GetChildById(new_parent_id); | 267 ViewTreeNode* old_parent = view_manager_->GetNodeById(old_parent_id); |
262 ViewTreeNode* old_parent = | |
263 view_manager_->tree()->GetChildById(old_parent_id); | |
264 ViewTreeNode* node = NULL; | 268 ViewTreeNode* node = NULL; |
265 if (old_parent) { | 269 if (old_parent) { |
266 // Existing node, mapped in this connection's tree. | 270 // Existing node, mapped in this connection's tree. |
267 // TODO(beng): verify this is actually true. | 271 // TODO(beng): verify this is actually true. |
268 node = view_manager_->tree()->GetChildById(node_id); | 272 node = view_manager_->GetNodeById(node_id); |
269 DCHECK_EQ(node->parent(), old_parent); | 273 DCHECK_EQ(node->parent(), old_parent); |
270 } else { | 274 } else { |
271 // New node, originating from another connection. | 275 // New node, originating from another connection. |
272 node = new ViewTreeNode; | 276 node = ViewTreeNodePrivate::LocalCreate(); |
273 ViewTreeNodePrivate private_node(node); | 277 ViewTreeNodePrivate private_node(node); |
274 private_node.set_view_manager(view_manager_); | 278 private_node.set_view_manager(view_manager_); |
275 private_node.set_id(node_id); | 279 private_node.set_id(node_id); |
| 280 ViewManagerPrivate(view_manager_).AddNode(node->id(), node); |
276 } | 281 } |
277 ViewTreeNodePrivate(new_parent).LocalAddChild(node); | 282 if (new_parent) |
| 283 ViewTreeNodePrivate(new_parent).LocalAddChild(node); |
| 284 else |
| 285 ViewTreeNodePrivate(old_parent).LocalRemoveChild(node); |
278 } | 286 } |
279 } | 287 } |
280 | 288 |
281 void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node, | 289 void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node, |
282 uint32_t new_view_id, | 290 uint32_t new_view_id, |
283 uint32_t old_view_id, | 291 uint32_t old_view_id, |
284 uint32_t change_id) { | 292 uint32_t change_id) { |
285 // .. | 293 // .. |
286 } | 294 } |
287 | 295 |
| 296 void ViewManagerSynchronizer::OnNodeDeleted(uint32_t node_id, |
| 297 uint32_t change_id) { |
| 298 if (change_id == 0) { |
| 299 ViewTreeNode* node = view_manager_->GetNodeById(node_id); |
| 300 if (node) |
| 301 ViewTreeNodePrivate(node).LocalDestroy(); |
| 302 } |
| 303 } |
| 304 |
288 //////////////////////////////////////////////////////////////////////////////// | 305 //////////////////////////////////////////////////////////////////////////////// |
289 // ViewManagerSynchronizer, private: | 306 // ViewManagerSynchronizer, private: |
290 | 307 |
291 void ViewManagerSynchronizer::ScheduleSync() { | 308 void ViewManagerSynchronizer::ScheduleSync() { |
| 309 if (sync_factory_.HasWeakPtrs()) |
| 310 return; |
292 base::MessageLoop::current()->PostTask( | 311 base::MessageLoop::current()->PostTask( |
293 FROM_HERE, | 312 FROM_HERE, |
294 base::Bind(&ViewManagerSynchronizer::DoSync, base::Unretained(this))); | 313 base::Bind(&ViewManagerSynchronizer::DoSync, sync_factory_.GetWeakPtr())); |
295 } | 314 } |
296 | 315 |
297 void ViewManagerSynchronizer::DoSync() { | 316 void ViewManagerSynchronizer::DoSync() { |
298 // The service connection may not be set up yet. OnConnectionEstablished() | 317 // The service connection may not be set up yet. OnConnectionEstablished() |
299 // will schedule another sync when it is. | 318 // will schedule another sync when it is. |
300 if (!connected_) | 319 if (!connected_) |
301 return; | 320 return; |
302 | 321 |
303 Transactions::const_iterator it = pending_transactions_.begin(); | 322 Transactions::const_iterator it = pending_transactions_.begin(); |
304 for (; it != pending_transactions_.end(); ++it) { | 323 for (; it != pending_transactions_.end(); ++it) { |
(...skipping 24 matching lines...) Expand all Loading... |
329 ViewTreeNode* last_node = NULL; | 348 ViewTreeNode* last_node = NULL; |
330 for (size_t i = 0; i < nodes.size(); ++i) { | 349 for (size_t i = 0; i < nodes.size(); ++i) { |
331 if (last_node && nodes[i].parent_id() == last_node->id()) { | 350 if (last_node && nodes[i].parent_id() == last_node->id()) { |
332 parents.push_back(last_node); | 351 parents.push_back(last_node); |
333 } else if (!parents.empty()) { | 352 } else if (!parents.empty()) { |
334 while (parents.back()->id() != nodes[i].parent_id()) | 353 while (parents.back()->id() != nodes[i].parent_id()) |
335 parents.pop_back(); | 354 parents.pop_back(); |
336 } | 355 } |
337 // We don't use the ctor that takes a ViewManager here, since it will call | 356 // We don't use the ctor that takes a ViewManager here, since it will call |
338 // back to the service and attempt to create a new node. | 357 // back to the service and attempt to create a new node. |
339 ViewTreeNode* node = new ViewTreeNode; | 358 ViewTreeNode* node = ViewTreeNodePrivate::LocalCreate(); |
340 ViewTreeNodePrivate private_node(node); | 359 ViewTreeNodePrivate private_node(node); |
341 private_node.set_view_manager(view_manager_); | 360 private_node.set_view_manager(view_manager_); |
342 private_node.set_id(nodes[i].node_id()); | 361 private_node.set_id(nodes[i].node_id()); |
343 if (!parents.empty()) | 362 if (!parents.empty()) |
344 ViewTreeNodePrivate(parents.back()).LocalAddChild(node); | 363 ViewTreeNodePrivate(parents.back()).LocalAddChild(node); |
345 if (!last_node) | 364 if (!last_node) |
346 root = node; | 365 root = node; |
347 last_node = node; | 366 last_node = node; |
| 367 ViewManagerPrivate(view_manager_).AddNode(node->id(), node); |
348 } | 368 } |
349 ViewManagerPrivate(view_manager_).SetRoot(root); | 369 ViewManagerPrivate(view_manager_).set_root(root); |
350 if (init_loop_) | 370 if (init_loop_) |
351 init_loop_->Quit(); | 371 init_loop_->Quit(); |
352 } | 372 } |
353 | 373 |
354 } // namespace view_manager | 374 } // namespace view_manager |
355 } // namespace services | 375 } // namespace services |
356 } // namespace mojo | 376 } // namespace mojo |
OLD | NEW |