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
3 // found in the LICENSE file.
4
5 #include "mojo/services/public/cpp/view_manager/lib/view_manager_client_impl.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h"
9 #include "mojo/public/cpp/application/application.h"
10 #include "mojo/public/cpp/application/connect.h"
11 #include "mojo/public/interfaces/service_provider/service_provider.mojom.h"
12 #include "mojo/services/public/cpp/view_manager/lib/node_private.h"
13 #include "mojo/services/public/cpp/view_manager/lib/view_private.h"
14 #include "mojo/services/public/cpp/view_manager/node_observer.h"
15 #include "mojo/services/public/cpp/view_manager/util.h"
16 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
17 #include "mojo/services/public/cpp/view_manager/view_observer.h"
18 #include "third_party/skia/include/core/SkBitmap.h"
19 #include "ui/gfx/codec/png_codec.h"
20
21 namespace mojo {
22 namespace view_manager {
23
MakeTransportId(ConnectionSpecificId connection_id,ConnectionSpecificId local_id)24 Id MakeTransportId(ConnectionSpecificId connection_id,
25 ConnectionSpecificId local_id) {
26 return (connection_id << 16) | local_id;
27 }
28
29 // Helper called to construct a local node/view object from transport data.
AddNodeToViewManager(ViewManagerClientImpl * client,Node * parent,Id node_id,Id view_id,const gfx::Rect & bounds)30 Node* AddNodeToViewManager(ViewManagerClientImpl* client,
31 Node* parent,
32 Id node_id,
33 Id view_id,
34 const gfx::Rect& bounds) {
35 // We don't use the ctor that takes a ViewManager here, since it will call
36 // back to the service and attempt to create a new node.
37 Node* node = NodePrivate::LocalCreate();
38 NodePrivate private_node(node);
39 private_node.set_view_manager(client);
40 private_node.set_id(node_id);
41 private_node.LocalSetBounds(gfx::Rect(), bounds);
42 if (parent)
43 NodePrivate(parent).LocalAddChild(node);
44 client->AddNode(node);
45
46 // View.
47 if (view_id != 0) {
48 View* view = ViewPrivate::LocalCreate();
49 ViewPrivate private_view(view);
50 private_view.set_view_manager(client);
51 private_view.set_id(view_id);
52 private_view.set_node(node);
53 // TODO(beng): this broadcasts notifications locally... do we want this? I
54 // don't think so. same story for LocalAddChild above!
55 private_node.LocalSetActiveView(view);
56 client->AddView(view);
57 }
58 return node;
59 }
60
BuildNodeTree(ViewManagerClientImpl * client,const Array<NodeDataPtr> & nodes)61 Node* BuildNodeTree(ViewManagerClientImpl* client,
62 const Array<NodeDataPtr>& nodes) {
63 std::vector<Node*> parents;
64 Node* root = NULL;
65 Node* last_node = NULL;
66 for (size_t i = 0; i < nodes.size(); ++i) {
67 if (last_node && nodes[i]->parent_id == last_node->id()) {
68 parents.push_back(last_node);
69 } else if (!parents.empty()) {
70 while (parents.back()->id() != nodes[i]->parent_id)
71 parents.pop_back();
72 }
73 Node* node = AddNodeToViewManager(
74 client,
75 !parents.empty() ? parents.back() : NULL,
76 nodes[i]->node_id,
77 nodes[i]->view_id,
78 nodes[i]->bounds.To<gfx::Rect>());
79 if (!last_node)
80 root = node;
81 last_node = node;
82 }
83 return root;
84 }
85
86 // Responsible for removing a root from the ViewManager when that node is
87 // destroyed.
88 class RootObserver : public NodeObserver {
89 public:
RootObserver(Node * root)90 explicit RootObserver(Node* root) : root_(root) {}
~RootObserver()91 virtual ~RootObserver() {}
92
93 private:
94 // Overridden from NodeObserver:
OnNodeDestroy(Node * node,DispositionChangePhase phase)95 virtual void OnNodeDestroy(Node* node,
96 DispositionChangePhase phase) OVERRIDE {
97 DCHECK_EQ(node, root_);
98 if (phase != NodeObserver::DISPOSITION_CHANGED)
99 return;
100 static_cast<ViewManagerClientImpl*>(
101 NodePrivate(root_).view_manager())->RemoveRoot(root_);
102 delete this;
103 }
104
105 Node* root_;
106
107 DISALLOW_COPY_AND_ASSIGN(RootObserver);
108 };
109
110 class ViewManagerTransaction {
111 public:
~ViewManagerTransaction()112 virtual ~ViewManagerTransaction() {}
113
Commit()114 void Commit() {
115 DCHECK(!committed_);
116 DoCommit();
117 committed_ = true;
118 }
119
committed() const120 bool committed() const { return committed_; }
121
122 protected:
ViewManagerTransaction(ViewManagerClientImpl * client)123 explicit ViewManagerTransaction(ViewManagerClientImpl* client)
124 : committed_(false),
125 client_(client) {
126 }
127
128 // Overridden to perform transaction-specific commit actions.
129 virtual void DoCommit() = 0;
130
131 // Overridden to perform transaction-specific cleanup on commit ack from the
132 // service.
133 virtual void DoActionCompleted(bool success) = 0;
134
service()135 ViewManagerService* service() { return client_->service_; }
136
GetAndAdvanceNextServerChangeId()137 Id GetAndAdvanceNextServerChangeId() {
138 return client_->next_server_change_id_++;
139 }
140
ActionCompletedCallback()141 base::Callback<void(bool)> ActionCompletedCallback() {
142 return base::Bind(&ViewManagerTransaction::OnActionCompleted,
143 base::Unretained(this));
144 }
145
146 private:
147 // General callback to be used for commits to the service.
OnActionCompleted(bool success)148 void OnActionCompleted(bool success) {
149 DCHECK(success);
150 DoActionCompleted(success);
151 client_->RemoveFromPendingQueue(this);
152 }
153
154 bool committed_;
155 ViewManagerClientImpl* client_;
156
157 DISALLOW_COPY_AND_ASSIGN(ViewManagerTransaction);
158 };
159
160 class CreateViewTransaction : public ViewManagerTransaction {
161 public:
CreateViewTransaction(Id view_id,ViewManagerClientImpl * client)162 CreateViewTransaction(Id view_id, ViewManagerClientImpl* client)
163 : ViewManagerTransaction(client),
164 view_id_(view_id) {}
~CreateViewTransaction()165 virtual ~CreateViewTransaction() {}
166
167 private:
168 // Overridden from ViewManagerTransaction:
DoCommit()169 virtual void DoCommit() OVERRIDE {
170 service()->CreateView(view_id_, ActionCompletedCallback());
171 }
DoActionCompleted(bool success)172 virtual void DoActionCompleted(bool success) OVERRIDE {
173 // TODO(beng): failure.
174 }
175
176 const Id view_id_;
177
178 DISALLOW_COPY_AND_ASSIGN(CreateViewTransaction);
179 };
180
181 class DestroyViewTransaction : public ViewManagerTransaction {
182 public:
DestroyViewTransaction(Id view_id,ViewManagerClientImpl * client)183 DestroyViewTransaction(Id view_id, ViewManagerClientImpl* client)
184 : ViewManagerTransaction(client),
185 view_id_(view_id) {}
~DestroyViewTransaction()186 virtual ~DestroyViewTransaction() {}
187
188 private:
189 // Overridden from ViewManagerTransaction:
DoCommit()190 virtual void DoCommit() OVERRIDE {
191 service()->DeleteView(view_id_, ActionCompletedCallback());
192 }
DoActionCompleted(bool success)193 virtual void DoActionCompleted(bool success) OVERRIDE {
194 // TODO(beng): recovery?
195 }
196
197 const Id view_id_;
198
199 DISALLOW_COPY_AND_ASSIGN(DestroyViewTransaction);
200 };
201
202 class CreateNodeTransaction : public ViewManagerTransaction {
203 public:
CreateNodeTransaction(Id node_id,ViewManagerClientImpl * client)204 CreateNodeTransaction(Id node_id, ViewManagerClientImpl* client)
205 : ViewManagerTransaction(client),
206 node_id_(node_id) {}
~CreateNodeTransaction()207 virtual ~CreateNodeTransaction() {}
208
209 private:
210 // Overridden from ViewManagerTransaction:
DoCommit()211 virtual void DoCommit() OVERRIDE {
212 service()->CreateNode(node_id_, ActionCompletedCallback());
213 }
DoActionCompleted(bool success)214 virtual void DoActionCompleted(bool success) OVERRIDE {
215 // TODO(beng): Failure means we tried to create with an extant id for this
216 // connection. It also could mean we tried to do something
217 // invalid, or we tried applying a change out of order. Figure
218 // out what to do.
219 }
220
221 const Id node_id_;
222
223 DISALLOW_COPY_AND_ASSIGN(CreateNodeTransaction);
224 };
225
226 class DestroyNodeTransaction : public ViewManagerTransaction {
227 public:
DestroyNodeTransaction(Id node_id,ViewManagerClientImpl * client)228 DestroyNodeTransaction(Id node_id, ViewManagerClientImpl* client)
229 : ViewManagerTransaction(client),
230 node_id_(node_id) {}
~DestroyNodeTransaction()231 virtual ~DestroyNodeTransaction() {}
232
233 private:
234 // Overridden from ViewManagerTransaction:
DoCommit()235 virtual void DoCommit() OVERRIDE {
236 service()->DeleteNode(node_id_,
237 GetAndAdvanceNextServerChangeId(),
238 ActionCompletedCallback());
239 }
DoActionCompleted(bool success)240 virtual void DoActionCompleted(bool success) OVERRIDE {
241 // TODO(beng): recovery?
242 }
243
244 const Id node_id_;
245 DISALLOW_COPY_AND_ASSIGN(DestroyNodeTransaction);
246 };
247
248 class AddChildTransaction : public ViewManagerTransaction {
249 public:
AddChildTransaction(Id child_id,Id parent_id,ViewManagerClientImpl * client)250 AddChildTransaction(Id child_id,
251 Id parent_id,
252 ViewManagerClientImpl* client)
253 : ViewManagerTransaction(client),
254 child_id_(child_id),
255 parent_id_(parent_id) {}
~AddChildTransaction()256 virtual ~AddChildTransaction() {}
257
258 private:
259 // Overridden from ViewManagerTransaction:
DoCommit()260 virtual void DoCommit() OVERRIDE {
261 service()->AddNode(parent_id_,
262 child_id_,
263 GetAndAdvanceNextServerChangeId(),
264 ActionCompletedCallback());
265 }
266
DoActionCompleted(bool success)267 virtual void DoActionCompleted(bool success) OVERRIDE {
268 // TODO(beng): recovery?
269 }
270
271 const Id child_id_;
272 const Id parent_id_;
273
274 DISALLOW_COPY_AND_ASSIGN(AddChildTransaction);
275 };
276
277 class RemoveChildTransaction : public ViewManagerTransaction {
278 public:
RemoveChildTransaction(Id child_id,ViewManagerClientImpl * client)279 RemoveChildTransaction(Id child_id, ViewManagerClientImpl* client)
280 : ViewManagerTransaction(client),
281 child_id_(child_id) {}
~RemoveChildTransaction()282 virtual ~RemoveChildTransaction() {}
283
284 private:
285 // Overridden from ViewManagerTransaction:
DoCommit()286 virtual void DoCommit() OVERRIDE {
287 service()->RemoveNodeFromParent(
288 child_id_,
289 GetAndAdvanceNextServerChangeId(),
290 ActionCompletedCallback());
291 }
292
DoActionCompleted(bool success)293 virtual void DoActionCompleted(bool success) OVERRIDE {
294 // TODO(beng): recovery?
295 }
296
297 const Id child_id_;
298
299 DISALLOW_COPY_AND_ASSIGN(RemoveChildTransaction);
300 };
301
302 class ReorderNodeTransaction : public ViewManagerTransaction {
303 public:
ReorderNodeTransaction(Id node_id,Id relative_id,OrderDirection direction,ViewManagerClientImpl * client)304 ReorderNodeTransaction(Id node_id,
305 Id relative_id,
306 OrderDirection direction,
307 ViewManagerClientImpl* client)
308 : ViewManagerTransaction(client),
309 node_id_(node_id),
310 relative_id_(relative_id),
311 direction_(direction) {}
~ReorderNodeTransaction()312 virtual ~ReorderNodeTransaction() {}
313
314 private:
315 // Overridden from ViewManagerTransaction:
DoCommit()316 virtual void DoCommit() OVERRIDE {
317 service()->ReorderNode(node_id_,
318 relative_id_,
319 direction_,
320 GetAndAdvanceNextServerChangeId(),
321 ActionCompletedCallback());
322 }
323
DoActionCompleted(bool success)324 virtual void DoActionCompleted(bool success) OVERRIDE {
325 // TODO(beng): recovery?
326 }
327
328 const Id node_id_;
329 const Id relative_id_;
330 const OrderDirection direction_;
331
332 DISALLOW_COPY_AND_ASSIGN(ReorderNodeTransaction);
333 };
334
335 class SetActiveViewTransaction : public ViewManagerTransaction {
336 public:
SetActiveViewTransaction(Id node_id,Id view_id,ViewManagerClientImpl * client)337 SetActiveViewTransaction(Id node_id,
338 Id view_id,
339 ViewManagerClientImpl* client)
340 : ViewManagerTransaction(client),
341 node_id_(node_id),
342 view_id_(view_id) {}
~SetActiveViewTransaction()343 virtual ~SetActiveViewTransaction() {}
344
345 private:
346 // Overridden from ViewManagerTransaction:
DoCommit()347 virtual void DoCommit() OVERRIDE {
348 service()->SetView(node_id_, view_id_, ActionCompletedCallback());
349 }
DoActionCompleted(bool success)350 virtual void DoActionCompleted(bool success) OVERRIDE {
351 // TODO(beng): recovery?
352 }
353
354 const Id node_id_;
355 const Id view_id_;
356
357 DISALLOW_COPY_AND_ASSIGN(SetActiveViewTransaction);
358 };
359
360 class SetBoundsTransaction : public ViewManagerTransaction {
361 public:
SetBoundsTransaction(Id node_id,const gfx::Rect & bounds,ViewManagerClientImpl * client)362 SetBoundsTransaction(Id node_id,
363 const gfx::Rect& bounds,
364 ViewManagerClientImpl* client)
365 : ViewManagerTransaction(client),
366 node_id_(node_id),
367 bounds_(bounds) {}
~SetBoundsTransaction()368 virtual ~SetBoundsTransaction() {}
369
370 private:
371 // Overridden from ViewManagerTransaction:
DoCommit()372 virtual void DoCommit() OVERRIDE {
373 service()->SetNodeBounds(
374 node_id_, Rect::From(bounds_), ActionCompletedCallback());
375 }
DoActionCompleted(bool success)376 virtual void DoActionCompleted(bool success) OVERRIDE {
377 // TODO(beng): recovery?
378 }
379
380 const Id node_id_;
381 const gfx::Rect bounds_;
382
383 DISALLOW_COPY_AND_ASSIGN(SetBoundsTransaction);
384 };
385
386 class SetViewContentsTransaction : public ViewManagerTransaction {
387 public:
SetViewContentsTransaction(Id view_id,const SkBitmap & contents,ViewManagerClientImpl * client)388 SetViewContentsTransaction(Id view_id,
389 const SkBitmap& contents,
390 ViewManagerClientImpl* client)
391 : ViewManagerTransaction(client),
392 view_id_(view_id),
393 contents_(contents) {}
~SetViewContentsTransaction()394 virtual ~SetViewContentsTransaction() {}
395
396 private:
397 // Overridden from ViewManagerTransaction:
DoCommit()398 virtual void DoCommit() OVERRIDE {
399 std::vector<unsigned char> data;
400 gfx::PNGCodec::EncodeBGRASkBitmap(contents_, false, &data);
401
402 void* memory = NULL;
403 ScopedSharedBufferHandle duped;
404 bool result = CreateMapAndDupSharedBuffer(data.size(),
405 &memory,
406 &shared_state_handle_,
407 &duped);
408 if (!result)
409 return;
410
411 memcpy(memory, &data[0], data.size());
412
413 service()->SetViewContents(view_id_, duped.Pass(),
414 static_cast<uint32_t>(data.size()),
415 ActionCompletedCallback());
416 }
DoActionCompleted(bool success)417 virtual void DoActionCompleted(bool success) OVERRIDE {
418 // TODO(beng): recovery?
419 }
420
CreateMapAndDupSharedBuffer(size_t size,void ** memory,ScopedSharedBufferHandle * handle,ScopedSharedBufferHandle * duped)421 bool CreateMapAndDupSharedBuffer(size_t size,
422 void** memory,
423 ScopedSharedBufferHandle* handle,
424 ScopedSharedBufferHandle* duped) {
425 MojoResult result = CreateSharedBuffer(NULL, size, handle);
426 if (result != MOJO_RESULT_OK)
427 return false;
428 DCHECK(handle->is_valid());
429
430 result = DuplicateBuffer(handle->get(), NULL, duped);
431 if (result != MOJO_RESULT_OK)
432 return false;
433 DCHECK(duped->is_valid());
434
435 result = MapBuffer(
436 handle->get(), 0, size, memory, MOJO_MAP_BUFFER_FLAG_NONE);
437 if (result != MOJO_RESULT_OK)
438 return false;
439 DCHECK(*memory);
440
441 return true;
442 }
443
444 const Id view_id_;
445 const SkBitmap contents_;
446 ScopedSharedBufferHandle shared_state_handle_;
447
448 DISALLOW_COPY_AND_ASSIGN(SetViewContentsTransaction);
449 };
450
451 class EmbedTransaction : public ViewManagerTransaction {
452 public:
EmbedTransaction(const String & url,Id node_id,ViewManagerClientImpl * client)453 EmbedTransaction(const String& url,
454 Id node_id,
455 ViewManagerClientImpl* client)
456 : ViewManagerTransaction(client),
457 url_(url),
458 node_id_(node_id) {}
~EmbedTransaction()459 virtual ~EmbedTransaction() {}
460
461 private:
462 // Overridden from ViewManagerTransaction:
DoCommit()463 virtual void DoCommit() OVERRIDE {
464 std::vector<Id> ids;
465 ids.push_back(node_id_);
466 service()->Embed(url_, Array<Id>::From(ids), ActionCompletedCallback());
467 }
DoActionCompleted(bool success)468 virtual void DoActionCompleted(bool success) OVERRIDE {
469 // TODO(beng): recovery?
470 }
471
472 const String url_;
473 const Id node_id_;
474
475 DISALLOW_COPY_AND_ASSIGN(EmbedTransaction);
476 };
477
478 class SetFocusTransaction : public ViewManagerTransaction {
479 public:
SetFocusTransaction(Id node_id,ViewManagerClientImpl * client)480 SetFocusTransaction(Id node_id, ViewManagerClientImpl* client)
481 : ViewManagerTransaction(client),
482 node_id_(node_id) {}
~SetFocusTransaction()483 virtual ~SetFocusTransaction() {}
484
485 private:
486 // Overridden from ViewManagerTransaction:
DoCommit()487 virtual void DoCommit() OVERRIDE {
488 service()->SetFocus(node_id_, ActionCompletedCallback());
489 }
DoActionCompleted(bool success)490 virtual void DoActionCompleted(bool success) OVERRIDE {
491 // TODO(beng): recovery?
492 }
493
494 const Id node_id_;
495
496 DISALLOW_COPY_AND_ASSIGN(SetFocusTransaction);
497 };
498
ViewManagerClientImpl(ViewManagerDelegate * delegate)499 ViewManagerClientImpl::ViewManagerClientImpl(ViewManagerDelegate* delegate)
500 : connected_(false),
501 connection_id_(0),
502 next_id_(1),
503 next_server_change_id_(0),
504 delegate_(delegate) {}
505
~ViewManagerClientImpl()506 ViewManagerClientImpl::~ViewManagerClientImpl() {
507 while (!nodes_.empty()) {
508 IdToNodeMap::iterator it = nodes_.begin();
509 if (OwnsNode(it->second->id()))
510 it->second->Destroy();
511 else
512 nodes_.erase(it);
513 }
514 while (!views_.empty()) {
515 IdToViewMap::iterator it = views_.begin();
516 if (OwnsView(it->second->id()))
517 it->second->Destroy();
518 else
519 views_.erase(it);
520 }
521 }
522
CreateNode()523 Id ViewManagerClientImpl::CreateNode() {
524 DCHECK(connected_);
525 const Id node_id(MakeTransportId(connection_id_, ++next_id_));
526 pending_transactions_.push_back(new CreateNodeTransaction(node_id, this));
527 Sync();
528 return node_id;
529 }
530
DestroyNode(Id node_id)531 void ViewManagerClientImpl::DestroyNode(Id node_id) {
532 DCHECK(connected_);
533 pending_transactions_.push_back(new DestroyNodeTransaction(node_id, this));
534 Sync();
535 }
536
CreateView()537 Id ViewManagerClientImpl::CreateView() {
538 DCHECK(connected_);
539 const Id view_id(MakeTransportId(connection_id_, ++next_id_));
540 pending_transactions_.push_back(new CreateViewTransaction(view_id, this));
541 Sync();
542 return view_id;
543 }
544
DestroyView(Id view_id)545 void ViewManagerClientImpl::DestroyView(Id view_id) {
546 DCHECK(connected_);
547 pending_transactions_.push_back(new DestroyViewTransaction(view_id, this));
548 Sync();
549 }
550
AddChild(Id child_id,Id parent_id)551 void ViewManagerClientImpl::AddChild(Id child_id,
552 Id parent_id) {
553 DCHECK(connected_);
554 pending_transactions_.push_back(
555 new AddChildTransaction(child_id, parent_id, this));
556 Sync();
557 }
558
RemoveChild(Id child_id,Id parent_id)559 void ViewManagerClientImpl::RemoveChild(Id child_id, Id parent_id) {
560 DCHECK(connected_);
561 pending_transactions_.push_back(new RemoveChildTransaction(child_id, this));
562 Sync();
563 }
564
Reorder(Id node_id,Id relative_node_id,OrderDirection direction)565 void ViewManagerClientImpl::Reorder(
566 Id node_id,
567 Id relative_node_id,
568 OrderDirection direction) {
569 DCHECK(connected_);
570 pending_transactions_.push_back(
571 new ReorderNodeTransaction(node_id, relative_node_id, direction, this));
572 Sync();
573 }
574
OwnsNode(Id id) const575 bool ViewManagerClientImpl::OwnsNode(Id id) const {
576 return HiWord(id) == connection_id_;
577 }
578
OwnsView(Id id) const579 bool ViewManagerClientImpl::OwnsView(Id id) const {
580 return HiWord(id) == connection_id_;
581 }
582
SetActiveView(Id node_id,Id view_id)583 void ViewManagerClientImpl::SetActiveView(Id node_id, Id view_id) {
584 DCHECK(connected_);
585 pending_transactions_.push_back(
586 new SetActiveViewTransaction(node_id, view_id, this));
587 Sync();
588 }
589
SetBounds(Id node_id,const gfx::Rect & bounds)590 void ViewManagerClientImpl::SetBounds(Id node_id, const gfx::Rect& bounds) {
591 DCHECK(connected_);
592 pending_transactions_.push_back(
593 new SetBoundsTransaction(node_id, bounds, this));
594 Sync();
595 }
596
SetViewContents(Id view_id,const SkBitmap & contents)597 void ViewManagerClientImpl::SetViewContents(Id view_id,
598 const SkBitmap& contents) {
599 DCHECK(connected_);
600 pending_transactions_.push_back(
601 new SetViewContentsTransaction(view_id, contents, this));
602 Sync();
603 }
604
SetFocus(Id node_id)605 void ViewManagerClientImpl::SetFocus(Id node_id) {
606 DCHECK(connected_);
607 pending_transactions_.push_back(new SetFocusTransaction(node_id, this));
608 Sync();
609 }
610
Embed(const String & url,Id node_id)611 void ViewManagerClientImpl::Embed(const String& url, Id node_id) {
612 DCHECK(connected_);
613 pending_transactions_.push_back(new EmbedTransaction(url, node_id, this));
614 Sync();
615 }
616
AddNode(Node * node)617 void ViewManagerClientImpl::AddNode(Node* node) {
618 DCHECK(nodes_.find(node->id()) == nodes_.end());
619 nodes_[node->id()] = node;
620 }
621
RemoveNode(Id node_id)622 void ViewManagerClientImpl::RemoveNode(Id node_id) {
623 IdToNodeMap::iterator it = nodes_.find(node_id);
624 if (it != nodes_.end())
625 nodes_.erase(it);
626 }
627
AddView(View * view)628 void ViewManagerClientImpl::AddView(View* view) {
629 DCHECK(views_.find(view->id()) == views_.end());
630 views_[view->id()] = view;
631 }
632
RemoveView(Id view_id)633 void ViewManagerClientImpl::RemoveView(Id view_id) {
634 IdToViewMap::iterator it = views_.find(view_id);
635 if (it != views_.end())
636 views_.erase(it);
637 }
638
639 ////////////////////////////////////////////////////////////////////////////////
640 // ViewManagerClientImpl, ViewManager implementation:
641
GetEmbedderURL() const642 const std::string& ViewManagerClientImpl::GetEmbedderURL() const {
643 return creator_url_;
644 }
645
GetRoots() const646 const std::vector<Node*>& ViewManagerClientImpl::GetRoots() const {
647 return roots_;
648 }
649
GetNodeById(Id id)650 Node* ViewManagerClientImpl::GetNodeById(Id id) {
651 IdToNodeMap::const_iterator it = nodes_.find(id);
652 return it != nodes_.end() ? it->second : NULL;
653 }
654
GetViewById(Id id)655 View* ViewManagerClientImpl::GetViewById(Id id) {
656 IdToViewMap::const_iterator it = views_.find(id);
657 return it != views_.end() ? it->second : NULL;
658 }
659
660 ////////////////////////////////////////////////////////////////////////////////
661 // ViewManagerClientImpl, InterfaceImpl overrides:
662
OnConnectionEstablished()663 void ViewManagerClientImpl::OnConnectionEstablished() {
664 service_ = client();
665 }
666
667 ////////////////////////////////////////////////////////////////////////////////
668 // ViewManagerClientImpl, ViewManagerClient implementation:
669
OnViewManagerConnectionEstablished(ConnectionSpecificId connection_id,const String & creator_url,Id next_server_change_id,Array<NodeDataPtr> nodes)670 void ViewManagerClientImpl::OnViewManagerConnectionEstablished(
671 ConnectionSpecificId connection_id,
672 const String& creator_url,
673 Id next_server_change_id,
674 Array<NodeDataPtr> nodes) {
675 connected_ = true;
676 connection_id_ = connection_id;
677 creator_url_ = TypeConverter<String, std::string>::ConvertFrom(creator_url);
678 next_server_change_id_ = next_server_change_id;
679
680 DCHECK(pending_transactions_.empty());
681 AddRoot(BuildNodeTree(this, nodes));
682 }
683
OnRootsAdded(Array<NodeDataPtr> nodes)684 void ViewManagerClientImpl::OnRootsAdded(Array<NodeDataPtr> nodes) {
685 AddRoot(BuildNodeTree(this, nodes));
686 }
687
OnServerChangeIdAdvanced(Id next_server_change_id)688 void ViewManagerClientImpl::OnServerChangeIdAdvanced(
689 Id next_server_change_id) {
690 next_server_change_id_ = next_server_change_id;
691 }
692
OnNodeBoundsChanged(Id node_id,RectPtr old_bounds,RectPtr new_bounds)693 void ViewManagerClientImpl::OnNodeBoundsChanged(Id node_id,
694 RectPtr old_bounds,
695 RectPtr new_bounds) {
696 Node* node = GetNodeById(node_id);
697 NodePrivate(node).LocalSetBounds(old_bounds.To<gfx::Rect>(),
698 new_bounds.To<gfx::Rect>());
699 }
700
OnNodeHierarchyChanged(Id node_id,Id new_parent_id,Id old_parent_id,Id server_change_id,mojo::Array<NodeDataPtr> nodes)701 void ViewManagerClientImpl::OnNodeHierarchyChanged(
702 Id node_id,
703 Id new_parent_id,
704 Id old_parent_id,
705 Id server_change_id,
706 mojo::Array<NodeDataPtr> nodes) {
707 next_server_change_id_ = server_change_id + 1;
708
709 BuildNodeTree(this, nodes);
710
711 Node* new_parent = GetNodeById(new_parent_id);
712 Node* old_parent = GetNodeById(old_parent_id);
713 Node* node = GetNodeById(node_id);
714 if (new_parent)
715 NodePrivate(new_parent).LocalAddChild(node);
716 else
717 NodePrivate(old_parent).LocalRemoveChild(node);
718 }
719
OnNodeReordered(Id node_id,Id relative_node_id,OrderDirection direction,Id server_change_id)720 void ViewManagerClientImpl::OnNodeReordered(Id node_id,
721 Id relative_node_id,
722 OrderDirection direction,
723 Id server_change_id) {
724 next_server_change_id_ = server_change_id + 1;
725
726 Node* node = GetNodeById(node_id);
727 Node* relative_node = GetNodeById(relative_node_id);
728 if (node && relative_node) {
729 NodePrivate(node).LocalReorder(relative_node, direction);
730 }
731 }
732
OnNodeDeleted(Id node_id,Id server_change_id)733 void ViewManagerClientImpl::OnNodeDeleted(Id node_id, Id server_change_id) {
734 next_server_change_id_ = server_change_id + 1;
735
736 Node* node = GetNodeById(node_id);
737 if (node)
738 NodePrivate(node).LocalDestroy();
739 }
740
OnNodeViewReplaced(Id node_id,Id new_view_id,Id old_view_id)741 void ViewManagerClientImpl::OnNodeViewReplaced(Id node_id,
742 Id new_view_id,
743 Id old_view_id) {
744 Node* node = GetNodeById(node_id);
745 View* new_view = GetViewById(new_view_id);
746 if (!new_view && new_view_id != 0) {
747 // This client wasn't aware of this View until now.
748 new_view = ViewPrivate::LocalCreate();
749 ViewPrivate private_view(new_view);
750 private_view.set_view_manager(this);
751 private_view.set_id(new_view_id);
752 private_view.set_node(node);
753 AddView(new_view);
754 }
755 View* old_view = GetViewById(old_view_id);
756 DCHECK_EQ(old_view, node->active_view());
757 NodePrivate(node).LocalSetActiveView(new_view);
758 }
759
OnViewDeleted(Id view_id)760 void ViewManagerClientImpl::OnViewDeleted(Id view_id) {
761 View* view = GetViewById(view_id);
762 if (view)
763 ViewPrivate(view).LocalDestroy();
764 }
765
OnViewInputEvent(Id view_id,EventPtr event,const Callback<void ()> & ack_callback)766 void ViewManagerClientImpl::OnViewInputEvent(
767 Id view_id,
768 EventPtr event,
769 const Callback<void()>& ack_callback) {
770 View* view = GetViewById(view_id);
771 if (view) {
772 FOR_EACH_OBSERVER(ViewObserver,
773 *ViewPrivate(view).observers(),
774 OnViewInputEvent(view, event));
775 }
776 ack_callback.Run();
777 }
778
DispatchOnViewInputEvent(Id view_id,EventPtr event)779 void ViewManagerClientImpl::DispatchOnViewInputEvent(Id view_id,
780 EventPtr event) {
781 // For now blindly bounce the message back to the server. Doing this means the
782 // event is sent to the correct target (|view_id|).
783 // Note: This function is only invoked on the window manager.
784 service_->DispatchOnViewInputEvent(view_id, event.Pass());
785 }
786
787 ////////////////////////////////////////////////////////////////////////////////
788 // ViewManagerClientImpl, private:
789
Sync()790 void ViewManagerClientImpl::Sync() {
791 // The service connection may not be set up yet. OnConnectionEstablished()
792 // will schedule another sync when it is.
793 if (!connected_)
794 return;
795
796 Transactions::const_iterator it = pending_transactions_.begin();
797 for (; it != pending_transactions_.end(); ++it) {
798 if (!(*it)->committed())
799 (*it)->Commit();
800 }
801 }
802
RemoveFromPendingQueue(ViewManagerTransaction * transaction)803 void ViewManagerClientImpl::RemoveFromPendingQueue(
804 ViewManagerTransaction* transaction) {
805 DCHECK_EQ(transaction, pending_transactions_.front());
806 pending_transactions_.erase(pending_transactions_.begin());
807 if (pending_transactions_.empty() && !changes_acked_callback_.is_null())
808 changes_acked_callback_.Run();
809 }
810
AddRoot(Node * root)811 void ViewManagerClientImpl::AddRoot(Node* root) {
812 // A new root must not already exist as a root or be contained by an existing
813 // hierarchy visible to this view manager.
814 std::vector<Node*>::const_iterator it = roots_.begin();
815 for (; it != roots_.end(); ++it) {
816 if (*it == root || (*it)->Contains(root))
817 return;
818 }
819 roots_.push_back(root);
820 root->AddObserver(new RootObserver(root));
821 delegate_->OnRootAdded(this, root);
822 }
823
RemoveRoot(Node * root)824 void ViewManagerClientImpl::RemoveRoot(Node* root) {
825 std::vector<Node*>::iterator it =
826 std::find(roots_.begin(), roots_.end(), root);
827 if (it != roots_.end())
828 roots_.erase(it);
829 }
830
831 ////////////////////////////////////////////////////////////////////////////////
832 // ViewManager, public:
833
834 // static
Create(Application * application,ViewManagerDelegate * delegate)835 void ViewManager::Create(Application* application,
836 ViewManagerDelegate* delegate) {
837 application->AddService<ViewManagerClientImpl>(delegate);
838 }
839
840 } // namespace view_manager
841 } // namespace mojo
842