| Index: mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
|
| diff --git a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
|
| index 886b5fdad1785584071144a258c61055eff91a74..617f8ff52b25c1a30635989fc29b648316d6fb12 100644
|
| --- a/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
|
| +++ b/mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc
|
| @@ -5,7 +5,6 @@
|
| #include "mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.h"
|
|
|
| #include "base/bind.h"
|
| -#include "base/message_loop/message_loop.h"
|
| #include "base/run_loop.h"
|
| #include "mojo/public/cpp/shell/service.h"
|
| #include "mojo/public/interfaces/shell/shell.mojom.h"
|
| @@ -33,7 +32,7 @@ class ViewManagerTransaction {
|
| }
|
|
|
| bool committed() const { return committed_; }
|
| - uint32_t change_id() const { return change_id_; }
|
| + TransportChangeId client_change_id() const { return client_change_id_; }
|
|
|
| // General callback to be used for commits to the service.
|
| void OnActionCompleted(bool success) {
|
| @@ -55,7 +54,7 @@ class ViewManagerTransaction {
|
| ViewManagerTransaction(TransactionType transaction_type,
|
| ViewManagerSynchronizer* synchronizer)
|
| : transaction_type_(transaction_type),
|
| - change_id_(synchronizer->GetNextChangeId()),
|
| + client_change_id_(synchronizer->GetNextClientChangeId()),
|
| committed_(false),
|
| synchronizer_(synchronizer) {
|
| }
|
| @@ -69,9 +68,13 @@ class ViewManagerTransaction {
|
|
|
| IViewManager* service() { return synchronizer_->service_.get(); }
|
|
|
| + TransportChangeId GetAndAdvanceNextServerChangeId() {
|
| + return synchronizer_->next_server_change_id_++;
|
| + }
|
| +
|
| private:
|
| const TransactionType transaction_type_;
|
| - const uint32_t change_id_;
|
| + const uint32_t client_change_id_;
|
| bool committed_;
|
| ViewManagerSynchronizer* synchronizer_;
|
|
|
| @@ -96,7 +99,9 @@ class CreateViewTreeNodeTransaction : public ViewManagerTransaction {
|
| }
|
| virtual void DoActionCompleted(bool success) OVERRIDE {
|
| // TODO(beng): Failure means we tried to create with an extant id for this
|
| - // connection. Figure out what to do.
|
| + // connection. It also could mean we tried to do something
|
| + // invalid, or we tried applying a change out of order. Figure
|
| + // out what to do.
|
| }
|
|
|
| const uint16_t node_id_;
|
| @@ -117,7 +122,7 @@ class DestroyViewTreeNodeTransaction : public ViewManagerTransaction {
|
| virtual void DoCommit() OVERRIDE {
|
| service()->DeleteNode(
|
| node_id_,
|
| - change_id(),
|
| + client_change_id(),
|
| base::Bind(&ViewManagerTransaction::OnActionCompleted,
|
| base::Unretained(this)));
|
| }
|
| @@ -153,14 +158,16 @@ class HierarchyTransaction : public ViewManagerTransaction {
|
| service()->AddNode(
|
| parent_id_,
|
| child_id_,
|
| - change_id(),
|
| + GetAndAdvanceNextServerChangeId(),
|
| + client_change_id(),
|
| base::Bind(&ViewManagerTransaction::OnActionCompleted,
|
| base::Unretained(this)));
|
| break;
|
| case TYPE_REMOVE:
|
| service()->RemoveNodeFromParent(
|
| child_id_,
|
| - change_id(),
|
| + GetAndAdvanceNextServerChangeId(),
|
| + client_change_id(),
|
| base::Bind(&ViewManagerTransaction::OnActionCompleted,
|
| base::Unretained(this)));
|
| break;
|
| @@ -184,7 +191,8 @@ ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager)
|
| connected_(false),
|
| connection_id_(0),
|
| next_id_(1),
|
| - next_change_id_(0),
|
| + next_client_change_id_(0),
|
| + next_server_change_id_(0),
|
| sync_factory_(this),
|
| init_loop_(NULL) {
|
| ConnectTo(ViewManagerPrivate(view_manager_).shell(), "mojo:mojo_view_manager",
|
| @@ -204,14 +212,14 @@ ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager)
|
| }
|
|
|
| ViewManagerSynchronizer::~ViewManagerSynchronizer() {
|
| - DoSync();
|
| + Sync();
|
| }
|
|
|
| TransportNodeId ViewManagerSynchronizer::CreateViewTreeNode() {
|
| DCHECK(connected_);
|
| uint16_t id = ++next_id_;
|
| pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this));
|
| - ScheduleSync();
|
| + Sync();
|
| return MakeTransportNodeId(connection_id_, id);
|
| }
|
|
|
| @@ -219,7 +227,7 @@ void ViewManagerSynchronizer::DestroyViewTreeNode(TransportNodeId node_id) {
|
| DCHECK(connected_);
|
| pending_transactions_.push_back(
|
| new DestroyViewTreeNodeTransaction(node_id, this));
|
| - ScheduleSync();
|
| + Sync();
|
| }
|
|
|
| void ViewManagerSynchronizer::AddChild(TransportNodeId child_id,
|
| @@ -230,7 +238,7 @@ void ViewManagerSynchronizer::AddChild(TransportNodeId child_id,
|
| child_id,
|
| parent_id,
|
| this));
|
| - ScheduleSync();
|
| + Sync();
|
| }
|
|
|
| void ViewManagerSynchronizer::RemoveChild(TransportNodeId child_id,
|
| @@ -241,7 +249,7 @@ void ViewManagerSynchronizer::RemoveChild(TransportNodeId child_id,
|
| child_id,
|
| parent_id,
|
| this));
|
| - ScheduleSync();
|
| + Sync();
|
| }
|
|
|
| bool ViewManagerSynchronizer::OwnsNode(TransportNodeId id) const {
|
| @@ -251,19 +259,27 @@ bool ViewManagerSynchronizer::OwnsNode(TransportNodeId id) const {
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // ViewManagerSynchronizer, IViewManagerClient implementation:
|
|
|
| -void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) {
|
| +void ViewManagerSynchronizer::OnConnectionEstablished(
|
| + TransportConnectionId connection_id,
|
| + TransportChangeId next_server_change_id) {
|
| connected_ = true;
|
| connection_id_ = connection_id;
|
| - ScheduleSync();
|
| + next_server_change_id_ = next_server_change_id;
|
| + Sync();
|
| }
|
|
|
| -void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node_id,
|
| - uint32_t new_parent_id,
|
| - uint32_t old_parent_id,
|
| - uint32_t change_id) {
|
| - if (change_id == 0) {
|
| - ViewTreeNode* new_parent = view_manager_->GetNodeById(new_parent_id);
|
| - ViewTreeNode* old_parent = view_manager_->GetNodeById(old_parent_id);
|
| +void ViewManagerSynchronizer::OnNodeHierarchyChanged(
|
| + uint32_t node_id,
|
| + uint32_t new_parent_id,
|
| + uint32_t old_parent_id,
|
| + TransportChangeId server_change_id,
|
| + TransportChangeId client_change_id) {
|
| + if (client_change_id == 0) {
|
| + // Change originated from another client.
|
| + ViewTreeNode* new_parent =
|
| + view_manager_->tree()->GetChildById(new_parent_id);
|
| + ViewTreeNode* old_parent =
|
| + view_manager_->tree()->GetChildById(old_parent_id);
|
| ViewTreeNode* node = NULL;
|
| if (old_parent) {
|
| // Existing node, mapped in this connection's tree.
|
| @@ -283,36 +299,32 @@ void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node_id,
|
| else
|
| ViewTreeNodePrivate(old_parent).LocalRemoveChild(node);
|
| }
|
| + next_server_change_id_ = server_change_id + 1;
|
| }
|
|
|
| -void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node,
|
| - uint32_t new_view_id,
|
| - uint32_t old_view_id,
|
| - uint32_t change_id) {
|
| - // ..
|
| -}
|
| -
|
| -void ViewManagerSynchronizer::OnNodeDeleted(uint32_t node_id,
|
| - uint32_t change_id) {
|
| - if (change_id == 0) {
|
| +void ViewManagerSynchronizer::OnNodeDeleted(
|
| + TransportNodeId node_id,
|
| + TransportChangeId server_change_id,
|
| + TransportChangeId client_change_id) {
|
| + next_server_change_id_ = server_change_id + 1;
|
| + if (client_change_id == 0) {
|
| ViewTreeNode* node = view_manager_->GetNodeById(node_id);
|
| if (node)
|
| ViewTreeNodePrivate(node).LocalDestroy();
|
| }
|
| }
|
|
|
| +void ViewManagerSynchronizer::OnNodeViewReplaced(uint32_t node,
|
| + uint32_t new_view_id,
|
| + uint32_t old_view_id,
|
| + uint32_t client_change_id) {
|
| + // ..
|
| +}
|
| +
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // ViewManagerSynchronizer, private:
|
|
|
| -void ViewManagerSynchronizer::ScheduleSync() {
|
| - if (sync_factory_.HasWeakPtrs())
|
| - return;
|
| - base::MessageLoop::current()->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&ViewManagerSynchronizer::DoSync, sync_factory_.GetWeakPtr()));
|
| -}
|
| -
|
| -void ViewManagerSynchronizer::DoSync() {
|
| +void ViewManagerSynchronizer::Sync() {
|
| // The service connection may not be set up yet. OnConnectionEstablished()
|
| // will schedule another sync when it is.
|
| if (!connected_)
|
| @@ -325,13 +337,13 @@ void ViewManagerSynchronizer::DoSync() {
|
| }
|
| }
|
|
|
| -uint32_t ViewManagerSynchronizer::GetNextChangeId() {
|
| +uint32_t ViewManagerSynchronizer::GetNextClientChangeId() {
|
| // TODO(beng): deal with change id collisions? Important in the "never ack'ed
|
| // change" case mentioned in OnNodeHierarchyChanged().
|
| // "0" is a special value passed to other connected clients, so we can't use
|
| // it.
|
| - next_change_id_ = std::max(1u, next_change_id_ + 1);
|
| - return next_change_id_;
|
| + next_client_change_id_ = std::max(1u, next_client_change_id_ + 1);
|
| + return next_client_change_id_;
|
| }
|
|
|
| void ViewManagerSynchronizer::RemoveFromPendingQueue(
|
|
|