| 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 |