Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / mojo / services / view_manager / root_node_manager.cc
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/view_manager/root_node_manager.h"
6
7 #include "base/logging.h"
8 #include "mojo/services/view_manager/view_manager_connection.h"
9 #include "ui/aura/env.h"
10
11 namespace mojo {
12 namespace services {
13 namespace view_manager {
14 namespace {
15
16 // Id for the root node.
17 const TransportConnectionSpecificNodeId kRootId = 1;
18
19 }  // namespace
20
21 RootNodeManager::Context::Context() {
22   // Pass in false as native viewport creates the PlatformEventSource.
23   aura::Env::CreateInstance(false);
24 }
25
26 RootNodeManager::Context::~Context() {
27 }
28
29 RootNodeManager::ScopedChange::ScopedChange(ViewManagerConnection* connection,
30                                             RootNodeManager* root,
31                                             TransportChangeId change_id)
32     : root_(root) {
33   root_->PrepareForChange(connection, change_id);
34 }
35
36 RootNodeManager::ScopedChange::~ScopedChange() {
37   root_->FinishChange();
38 }
39
40 RootNodeManager::RootNodeManager(Shell* shell)
41     : next_connection_id_(1),
42       root_view_manager_(shell, this),
43       root_(this, NodeId(0, kRootId)) {
44 }
45
46 RootNodeManager::~RootNodeManager() {
47   // All the connections should have been destroyed.
48   DCHECK(connection_map_.empty());
49 }
50
51 TransportConnectionId RootNodeManager::GetAndAdvanceNextConnectionId() {
52   const TransportConnectionId id = next_connection_id_++;
53   DCHECK_LT(id, next_connection_id_);
54   return id;
55 }
56
57 void RootNodeManager::AddConnection(ViewManagerConnection* connection) {
58   DCHECK_EQ(0u, connection_map_.count(connection->id()));
59   connection_map_[connection->id()] = connection;
60 }
61
62 void RootNodeManager::RemoveConnection(ViewManagerConnection* connection) {
63   connection_map_.erase(connection->id());
64 }
65
66 ViewManagerConnection* RootNodeManager::GetConnection(
67     TransportConnectionId connection_id) {
68   ConnectionMap::iterator i = connection_map_.find(connection_id);
69   return i == connection_map_.end() ? NULL : i->second;
70 }
71
72 Node* RootNodeManager::GetNode(const NodeId& id) {
73   if (id == root_.id())
74     return &root_;
75   ConnectionMap::iterator i = connection_map_.find(id.connection_id);
76   return i == connection_map_.end() ? NULL : i->second->GetNode(id);
77 }
78
79 View* RootNodeManager::GetView(const ViewId& id) {
80   ConnectionMap::iterator i = connection_map_.find(id.connection_id);
81   return i == connection_map_.end() ? NULL : i->second->GetView(id);
82 }
83
84 void RootNodeManager::NotifyNodeHierarchyChanged(const NodeId& node,
85                                                  const NodeId& new_parent,
86                                                  const NodeId& old_parent) {
87   for (ConnectionMap::iterator i = connection_map_.begin();
88        i != connection_map_.end(); ++i) {
89     const TransportChangeId change_id =
90         (change_ && i->first == change_->connection_id) ?
91         change_->change_id : 0;
92     i->second->NotifyNodeHierarchyChanged(
93         node, new_parent, old_parent, change_id);
94   }
95 }
96
97 void RootNodeManager::NotifyNodeViewReplaced(const NodeId& node,
98                                              const ViewId& new_view_id,
99                                              const ViewId& old_view_id) {
100   // TODO(sky): make a macro for this.
101   for (ConnectionMap::iterator i = connection_map_.begin();
102        i != connection_map_.end(); ++i) {
103     const TransportChangeId change_id =
104         (change_ && i->first == change_->connection_id) ?
105         change_->change_id : 0;
106     i->second->NotifyNodeViewReplaced(node, new_view_id, old_view_id,
107                                       change_id);
108   }
109 }
110
111 void RootNodeManager::NotifyNodeDeleted(const NodeId& node) {
112   for (ConnectionMap::iterator i = connection_map_.begin();
113        i != connection_map_.end(); ++i) {
114     const TransportChangeId change_id =
115         (change_ && i->first == change_->connection_id) ?
116         change_->change_id : 0;
117     i->second->NotifyNodeDeleted(node, change_id);
118   }
119 }
120
121 void RootNodeManager::PrepareForChange(ViewManagerConnection* connection,
122                                        TransportChangeId change_id) {
123   DCHECK(!change_.get());  // Should only ever have one change in flight.
124   change_.reset(new Change(connection->id(), change_id));
125 }
126
127 void RootNodeManager::FinishChange() {
128   DCHECK(change_.get());  // PrepareForChange/FinishChange should be balanced.
129   change_.reset();
130 }
131
132 void RootNodeManager::OnNodeHierarchyChanged(const NodeId& node,
133                                              const NodeId& new_parent,
134                                              const NodeId& old_parent) {
135   if (!root_view_manager_.in_setup())
136     NotifyNodeHierarchyChanged(node, new_parent, old_parent);
137 }
138
139 void RootNodeManager::OnNodeViewReplaced(const NodeId& node,
140                                          const ViewId& new_view_id,
141                                          const ViewId& old_view_id) {
142   NotifyNodeViewReplaced(node, new_view_id, old_view_id);
143 }
144
145 }  // namespace view_manager
146 }  // namespace services
147 }  // namespace mojo