Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(482)

Side by Side Diff: mojo/services/public/cpp/view_manager/lib/view_manager_synchronizer.cc

Issue 260863008: Add support for mapping node tree on the client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "mojo/public/cpp/bindings/allocation_scope.h" 9 #include "mojo/public/cpp/bindings/allocation_scope.h"
10 #include "mojo/public/interfaces/shell/shell.mojom.h" 10 #include "mojo/public/interfaces/shell/shell.mojom.h"
11 #include "mojo/services/public/cpp/view_manager/lib/view_manager_observer.h"
11 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h" 12 #include "mojo/services/public/cpp/view_manager/lib/view_manager_private.h"
13 #include "mojo/services/public/cpp/view_manager/lib/view_tree_node_private.h"
14 #include "mojo/services/public/cpp/view_manager/util.h"
12 15
13 namespace mojo { 16 namespace mojo {
14 namespace services { 17 namespace services {
15 namespace view_manager { 18 namespace view_manager {
16 19
20 const TransportNodeId kRootNodeId = 1;
21
17 class ViewManagerTransaction { 22 class ViewManagerTransaction {
18 public: 23 public:
19 virtual ~ViewManagerTransaction() {} 24 virtual ~ViewManagerTransaction() {}
20 25
21 void Commit() { 26 void Commit() {
22 DCHECK(!committed_); 27 DCHECK(!committed_);
23 DoCommit(); 28 DoCommit();
29 synchronizer_->NotifyCommit();
24 committed_ = true; 30 committed_ = true;
25 } 31 }
26 32
27 bool committed() const { return committed_; } 33 bool committed() const { return committed_; }
28 uint32_t change_id() const { return change_id_; } 34 uint32_t change_id() const { return change_id_; }
29 35
30 // General callback to be used for commits to the service. 36 // General callback to be used for commits to the service.
31 void OnActionCompleted(bool success) { 37 void OnActionCompleted(bool success) {
32 DCHECK(success); 38 DCHECK(success);
33 DoActionCompleted(success); 39 DoActionCompleted(success);
40 synchronizer_->NotifyCommitResponse(success);
34 synchronizer_->RemoveFromPendingQueue(this); 41 synchronizer_->RemoveFromPendingQueue(this);
35 } 42 }
36 43
37 protected: 44 protected:
38 enum TransactionType { 45 enum TransactionType {
39 // Node creation. 46 // Node creation and destruction.
40 TYPE_CREATE_VIEW_TREE_NODE, 47 TYPE_CREATE_VIEW_TREE_NODE,
48 TYPE_DESTROY_VIEW_TREE_NODE,
41 // Modifications to the hierarchy (addition of or removal of nodes from a 49 // Modifications to the hierarchy (addition of or removal of nodes from a
42 // parent.) 50 // parent.)
43 TYPE_HIERARCHY 51 TYPE_HIERARCHY
44 }; 52 };
45 53
46 ViewManagerTransaction(TransactionType transaction_type, 54 ViewManagerTransaction(TransactionType transaction_type,
47 ViewManagerSynchronizer* synchronizer) 55 ViewManagerSynchronizer* synchronizer)
48 : transaction_type_(transaction_type), 56 : transaction_type_(transaction_type),
49 change_id_(synchronizer->GetNextChangeId()), 57 change_id_(synchronizer->GetNextChangeId()),
50 committed_(false), 58 committed_(false),
51 synchronizer_(synchronizer) { 59 synchronizer_(synchronizer) {
52 } 60 }
53 61
54 // Overridden to perform transaction-specific commit actions. 62 // Overridden to perform transaction-specific commit actions.
55 virtual void DoCommit() = 0; 63 virtual void DoCommit() = 0;
56 64
57 // Overridden to perform transaction-specific cleanup on commit ack from the 65 // Overridden to perform transaction-specific cleanup on commit ack from the
58 // service. 66 // service.
59 virtual void DoActionCompleted(bool success) = 0; 67 virtual void DoActionCompleted(bool success) = 0;
60 68
61 IViewManager* service() { return synchronizer_->service_.get(); } 69 IViewManager* service() { return synchronizer_->service_.get(); }
62 70
63 uint32_t MakeTransportId(uint16_t id) { 71 TransportNodeId MakeTransportId(uint32_t id) {
64 return (synchronizer_->connection_id_ << 16) | id; 72 if (id == kRootNodeId || HiWord(id) != 0)
73 return id;
74 return (synchronizer_->connection_id_ << 16) | LoWord(id);
65 } 75 }
66 76
67 private: 77 private:
68 const TransactionType transaction_type_; 78 const TransactionType transaction_type_;
69 const uint32_t change_id_; 79 const uint32_t change_id_;
70 bool committed_; 80 bool committed_;
71 ViewManagerSynchronizer* synchronizer_; 81 ViewManagerSynchronizer* synchronizer_;
72 82
73 DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction); 83 DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
74 }; 84 };
75 85
76 class CreateViewTreeNodeTransaction 86 class CreateViewTreeNodeTransaction : public ViewManagerTransaction {
77 : public ViewManagerTransaction {
78 public: 87 public:
79 CreateViewTreeNodeTransaction(uint16_t node_id, 88 CreateViewTreeNodeTransaction(uint16_t node_id,
80 ViewManagerSynchronizer* synchronizer) 89 ViewManagerSynchronizer* synchronizer)
81 : ViewManagerTransaction(TYPE_CREATE_VIEW_TREE_NODE, synchronizer), 90 : ViewManagerTransaction(TYPE_CREATE_VIEW_TREE_NODE, synchronizer),
82 node_id_(node_id) {} 91 node_id_(node_id) {}
83 virtual ~CreateViewTreeNodeTransaction() {} 92 virtual ~CreateViewTreeNodeTransaction() {}
84 93
85 private: 94 private:
86 // Overridden from ViewManagerTransaction: 95 // Overridden from ViewManagerTransaction:
87 virtual void DoCommit() OVERRIDE { 96 virtual void DoCommit() OVERRIDE {
88 service()->CreateNode( 97 service()->CreateNode(
89 node_id_, 98 node_id_,
90 base::Bind(&ViewManagerTransaction::OnActionCompleted, 99 base::Bind(&ViewManagerTransaction::OnActionCompleted,
91 base::Unretained(this))); 100 base::Unretained(this)));
92 } 101 }
93
94 virtual void DoActionCompleted(bool success) OVERRIDE { 102 virtual void DoActionCompleted(bool success) OVERRIDE {
95 // TODO(beng): Failure means we tried to create with an extant id for this 103 // TODO(beng): Failure means we tried to create with an extant id for this
96 // connection. Figure out what to do. 104 // connection. Figure out what to do.
97 } 105 }
98 106
99 const uint16_t node_id_; 107 const uint16_t node_id_;
100 108
101 DISALLOW_COPY_AND_ASSIGN(CreateViewTreeNodeTransaction); 109 DISALLOW_COPY_AND_ASSIGN(CreateViewTreeNodeTransaction);
102 }; 110 };
103 111
112 class DestroyViewTreeNodeTransaction : public ViewManagerTransaction {
113 public:
114 DestroyViewTreeNodeTransaction(TransportNodeId node_id,
115 ViewManagerSynchronizer* synchronizer)
116 : ViewManagerTransaction(TYPE_DESTROY_VIEW_TREE_NODE, synchronizer),
117 node_id_(node_id) {}
118 virtual ~DestroyViewTreeNodeTransaction() {}
119
120 private:
121 // Overridden from ViewManagerTransaction:
122 virtual void DoCommit() OVERRIDE {
123 service()->DeleteNode(
124 node_id_,
125 change_id(),
126 base::Bind(&ViewManagerTransaction::OnActionCompleted,
127 base::Unretained(this)));
128 }
129 virtual void DoActionCompleted(bool success) OVERRIDE {
130 // TODO(beng): recovery?
131 }
132
133 TransportNodeId node_id_;
134 DISALLOW_COPY_AND_ASSIGN(DestroyViewTreeNodeTransaction);
135 };
136
104 class HierarchyTransaction : public ViewManagerTransaction { 137 class HierarchyTransaction : public ViewManagerTransaction {
105 public: 138 public:
106 enum HierarchyChangeType { 139 enum HierarchyChangeType {
107 TYPE_ADD, 140 TYPE_ADD,
108 TYPE_REMOVE 141 TYPE_REMOVE
109 }; 142 };
110 HierarchyTransaction(HierarchyChangeType hierarchy_change_type, 143 HierarchyTransaction(HierarchyChangeType hierarchy_change_type,
111 uint16_t child_id, 144 TransportNodeId child_id,
112 uint16_t parent_id, 145 TransportNodeId parent_id,
113 ViewManagerSynchronizer* synchronizer) 146 ViewManagerSynchronizer* synchronizer)
114 : ViewManagerTransaction(TYPE_HIERARCHY, synchronizer), 147 : ViewManagerTransaction(TYPE_HIERARCHY, synchronizer),
115 hierarchy_change_type_(hierarchy_change_type), 148 hierarchy_change_type_(hierarchy_change_type),
116 child_id_(child_id), 149 child_id_(child_id),
117 parent_id_(parent_id) {} 150 parent_id_(parent_id) {}
118 virtual ~HierarchyTransaction() {} 151 virtual ~HierarchyTransaction() {}
119 152
120 private: 153 private:
121 // Overridden from ViewManagerTransaction: 154 // Overridden from ViewManagerTransaction:
122 virtual void DoCommit() OVERRIDE { 155 virtual void DoCommit() OVERRIDE {
(...skipping 15 matching lines...) Expand all
138 break; 171 break;
139 } 172 }
140 } 173 }
141 174
142 virtual void DoActionCompleted(bool success) OVERRIDE { 175 virtual void DoActionCompleted(bool success) OVERRIDE {
143 // TODO(beng): Failure means either one of the nodes specified didn't exist, 176 // TODO(beng): Failure means either one of the nodes specified didn't exist,
144 // or we passed the same node id for both params. Roll back? 177 // or we passed the same node id for both params. Roll back?
145 } 178 }
146 179
147 const HierarchyChangeType hierarchy_change_type_; 180 const HierarchyChangeType hierarchy_change_type_;
148 const uint16_t child_id_; 181 const TransportNodeId child_id_;
149 const uint16_t parent_id_; 182 const TransportNodeId parent_id_;
150 183
151 DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction); 184 DISALLOW_COPY_AND_ASSIGN(HierarchyTransaction);
152 }; 185 };
153 186
154 ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager) 187 ViewManagerSynchronizer::ViewManagerSynchronizer(ViewManager* view_manager)
155 : view_manager_(view_manager), 188 : view_manager_(view_manager),
156 connected_(false), 189 connected_(false),
157 connection_id_(0), 190 connection_id_(0),
158 next_id_(0), 191 next_id_(1),
159 next_change_id_(0) { 192 next_change_id_(0) {
160 InterfacePipe<services::view_manager::IViewManager, AnyInterface> 193 InterfacePipe<services::view_manager::IViewManager, AnyInterface>
161 view_manager_pipe; 194 view_manager_pipe;
162 AllocationScope scope; 195 AllocationScope scope;
163 ViewManagerPrivate(view_manager_).shell()->Connect( 196 ViewManagerPrivate(view_manager_).shell()->Connect(
164 "mojo:mojo_view_manager", view_manager_pipe.handle_to_peer.Pass()); 197 "mojo:mojo_view_manager", view_manager_pipe.handle_to_peer.Pass());
165 service_.reset(view_manager_pipe.handle_to_self.Pass(), this); 198 service_.reset(view_manager_pipe.handle_to_self.Pass(), this);
166 } 199 }
167 200
168 ViewManagerSynchronizer::~ViewManagerSynchronizer() { 201 ViewManagerSynchronizer::~ViewManagerSynchronizer() {
169 } 202 }
170 203
171 uint16_t ViewManagerSynchronizer::CreateViewTreeNode() { 204 uint16_t ViewManagerSynchronizer::CreateViewTreeNode() {
172 uint16_t id = next_id_++; 205 uint16_t id = ++next_id_;
173 pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this)); 206 pending_transactions_.push_back(new CreateViewTreeNodeTransaction(id, this));
174 ScheduleSync(); 207 ScheduleSync();
175 return id; 208 return id;
176 } 209 }
177 210
178 void ViewManagerSynchronizer::AddChild(uint16_t child_id, uint16_t parent_id) { 211 void ViewManagerSynchronizer::DestroyViewTreeNode(TransportNodeId node_id) {
212 pending_transactions_.push_back(
213 new DestroyViewTreeNodeTransaction(node_id, this));
214 ScheduleSync();
215 }
216
217 void ViewManagerSynchronizer::AddChild(TransportNodeId child_id,
218 TransportNodeId parent_id) {
179 pending_transactions_.push_back( 219 pending_transactions_.push_back(
180 new HierarchyTransaction(HierarchyTransaction::TYPE_ADD, 220 new HierarchyTransaction(HierarchyTransaction::TYPE_ADD,
181 child_id, 221 child_id,
182 parent_id, 222 parent_id,
183 this)); 223 this));
184 ScheduleSync(); 224 ScheduleSync();
185 } 225 }
186 226
187 void ViewManagerSynchronizer::RemoveChild(uint16_t child_id, 227 void ViewManagerSynchronizer::RemoveChild(TransportNodeId child_id,
188 uint16_t parent_id) { 228 TransportNodeId parent_id) {
189 pending_transactions_.push_back( 229 pending_transactions_.push_back(
190 new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE, 230 new HierarchyTransaction(HierarchyTransaction::TYPE_REMOVE,
191 child_id, 231 child_id,
192 parent_id, 232 parent_id,
193 this)); 233 this));
194 ScheduleSync(); 234 ScheduleSync();
195 } 235 }
196 236
237 void ViewManagerSynchronizer::BuildNodeTree(
238 const Callback<void()>& callback) {
239 service_->GetNodeTree(
240 1,
241 base::Bind(&ViewManagerSynchronizer::OnTreeReceived,
242 base::Unretained(this),
243 callback));
244 }
245
197 //////////////////////////////////////////////////////////////////////////////// 246 ////////////////////////////////////////////////////////////////////////////////
198 // ViewManagerSynchronizer, IViewManagerClient implementation: 247 // ViewManagerSynchronizer, IViewManagerClient implementation:
199 248
200 void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) { 249 void ViewManagerSynchronizer::OnConnectionEstablished(uint16 connection_id) {
201 connected_ = true; 250 connected_ = true;
202 connection_id_ = connection_id; 251 connection_id_ = connection_id;
203 ScheduleSync(); 252 ScheduleSync();
253 FOR_EACH_OBSERVER(ViewManagerObserver,
254 *ViewManagerPrivate(view_manager_).observers(),
255 OnViewManagerConnected(view_manager_));
204 } 256 }
205 257
206 void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node, 258 void ViewManagerSynchronizer::OnNodeHierarchyChanged(uint32_t node,
207 uint32_t new_parent, 259 uint32_t new_parent,
208 uint32_t old_parent, 260 uint32_t old_parent,
209 uint32_t change_id) { 261 uint32_t change_id) {
210 if (change_id == 0) { 262 if (change_id == 0) {
211 // TODO(beng): Apply changes from another client. 263 // TODO(beng): Apply changes from another client.
212 } 264 }
213 } 265 }
(...skipping 29 matching lines...) Expand all
243 295
244 uint32_t ViewManagerSynchronizer::GetNextChangeId() { 296 uint32_t ViewManagerSynchronizer::GetNextChangeId() {
245 // TODO(beng): deal with change id collisions? Important in the "never ack'ed 297 // TODO(beng): deal with change id collisions? Important in the "never ack'ed
246 // change" case mentioned in OnNodeHierarchyChanged(). 298 // change" case mentioned in OnNodeHierarchyChanged().
247 // "0" is a special value passed to other connected clients, so we can't use 299 // "0" is a special value passed to other connected clients, so we can't use
248 // it. 300 // it.
249 next_change_id_ = std::max(1u, next_change_id_ + 1); 301 next_change_id_ = std::max(1u, next_change_id_ + 1);
250 return next_change_id_; 302 return next_change_id_;
251 } 303 }
252 304
305 void ViewManagerSynchronizer::NotifyCommit() {
306 FOR_EACH_OBSERVER(ViewManagerObserver,
307 *ViewManagerPrivate(view_manager_).observers(),
308 OnCommit(view_manager_));
309 }
310
311 void ViewManagerSynchronizer::NotifyCommitResponse(bool success) {
312 FOR_EACH_OBSERVER(ViewManagerObserver,
313 *ViewManagerPrivate(view_manager_).observers(),
314 OnCommitResponse(view_manager_, success));
315 }
316
253 void ViewManagerSynchronizer::RemoveFromPendingQueue( 317 void ViewManagerSynchronizer::RemoveFromPendingQueue(
254 ViewManagerTransaction* transaction) { 318 ViewManagerTransaction* transaction) {
255 DCHECK_EQ(transaction, pending_transactions_.front()); 319 DCHECK_EQ(transaction, pending_transactions_.front());
256 pending_transactions_.erase(pending_transactions_.begin()); 320 pending_transactions_.erase(pending_transactions_.begin());
257 } 321 }
258 322
323 void ViewManagerSynchronizer::OnTreeReceived(
324 const Callback<void()>& callback,
325 const Array<INode>& nodes) {
326 std::vector<ViewTreeNode*> parents;
327 ViewTreeNode* root = NULL;
328 ViewTreeNode* last_node = NULL;
329 for (size_t i = 0; i < nodes.size(); ++i) {
330 if (last_node && nodes[i].parent_id() == last_node->id()) {
331 parents.push_back(last_node);
332 } else if (!parents.empty()) {
333 while (parents.back()->id() != nodes[i].parent_id())
334 parents.pop_back();
335 }
336 // We don't use the ctor that takes a ViewManager here, since it will call
337 // back to the service and attempt to create a new node.
338 ViewTreeNode* node = new ViewTreeNode;
339 ViewTreeNodePrivate private_node(node);
340 private_node.set_view_manager(view_manager_);
341 private_node.set_id(nodes[i].node_id());
342 if (!parents.empty())
343 ViewTreeNodePrivate(parents.back()).LocalAddChild(node);
344 if (!last_node)
345 root = node;
346 last_node = node;
347 }
348 ViewManagerPrivate(view_manager_).set_tree(root);
349 callback.Run();
350 }
351
259 } // namespace view_manager 352 } // namespace view_manager
260 } // namespace services 353 } // namespace services
261 } // namespace mojo 354 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698