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/view_manager/view_manager_connection.h" | 5 #include "mojo/services/view_manager/view_manager_connection.h" |
6 | 6 |
7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
8 #include "mojo/services/view_manager/node.h" | 8 #include "mojo/services/view_manager/node.h" |
9 #include "mojo/services/view_manager/root_node_manager.h" | 9 #include "mojo/services/view_manager/root_node_manager.h" |
10 #include "mojo/services/view_manager/view.h" | |
11 | 10 |
12 namespace mojo { | 11 namespace mojo { |
13 namespace services { | 12 namespace services { |
14 namespace view_manager { | 13 namespace view_manager { |
15 | 14 |
16 ViewManagerConnection::ViewManagerConnection() : id_(0) { | 15 ViewManagerConnection::ViewManagerConnection() : id_(0) { |
17 } | 16 } |
18 | 17 |
19 ViewManagerConnection::~ViewManagerConnection() { | 18 ViewManagerConnection::~ViewManagerConnection() { |
20 // Delete any views we own. | |
21 while (!view_map_.empty()) { | |
22 bool result = DeleteViewImpl(this, view_map_.begin()->second->id(), 0); | |
23 DCHECK(result); | |
24 } | |
25 | |
26 // We're about to destroy all our nodes. Detach any views from them. | |
27 for (NodeMap::iterator i = node_map_.begin(); i != node_map_.end(); ++i) { | |
28 if (i->second->view()) { | |
29 bool result = SetViewImpl(i->second->id(), ViewId(), 0); | |
30 DCHECK(result); | |
31 } | |
32 } | |
33 | |
34 STLDeleteContainerPairSecondPointers(node_map_.begin(), node_map_.end()); | 19 STLDeleteContainerPairSecondPointers(node_map_.begin(), node_map_.end()); |
35 context()->RemoveConnection(this); | 20 context()->RemoveConnection(this); |
36 } | 21 } |
37 | 22 |
38 void ViewManagerConnection::Initialize( | 23 void ViewManagerConnection::Initialize( |
39 ServiceConnector<ViewManagerConnection, RootNodeManager>* service_factory, | 24 ServiceConnector<ViewManagerConnection, RootNodeManager>* service_factory, |
40 ScopedMessagePipeHandle client_handle) { | 25 ScopedMessagePipeHandle client_handle) { |
41 DCHECK_EQ(0, id_); // Should only get Initialize() once. | 26 DCHECK_EQ(0, id_); // Should only get Initialize() once. |
42 ServiceConnection<ViewManager, ViewManagerConnection, RootNodeManager>:: | 27 ServiceConnection<ViewManager, ViewManagerConnection, RootNodeManager>:: |
43 Initialize(service_factory, client_handle.Pass()); | 28 Initialize(service_factory, client_handle.Pass()); |
44 id_ = context()->GetAndAdvanceNextConnectionId(); | 29 id_ = context()->GetAndAdvanceNextConnectionId(); |
45 context()->AddConnection(this); | 30 context()->AddConnection(this); |
46 client()->OnConnectionEstablished(id_); | 31 client()->OnConnectionEstablished(id_); |
47 } | 32 } |
48 | 33 |
49 Node* ViewManagerConnection::GetNode(const NodeId& id) { | 34 Node* ViewManagerConnection::GetNode(const NodeId& id) { |
50 if (id_ == id.connection_id) { | 35 if (id_ == id.connection_id) { |
51 NodeMap::iterator i = node_map_.find(id.node_id); | 36 NodeMap::iterator i = node_map_.find(id.node_id); |
52 return i == node_map_.end() ? NULL : i->second; | 37 return i == node_map_.end() ? NULL : i->second; |
53 } | 38 } |
54 return context()->GetNode(id); | 39 return context()->GetNode(id); |
55 } | 40 } |
56 | 41 |
57 View* ViewManagerConnection::GetView(const ViewId& id) { | |
58 if (id_ == id.connection_id) { | |
59 ViewMap::const_iterator i = view_map_.find(id.view_id); | |
60 return i == view_map_.end() ? NULL : i->second; | |
61 } | |
62 return context()->GetView(id); | |
63 } | |
64 | |
65 void ViewManagerConnection::NotifyNodeHierarchyChanged( | 42 void ViewManagerConnection::NotifyNodeHierarchyChanged( |
66 const NodeId& node, | 43 const NodeId& node, |
67 const NodeId& new_parent, | 44 const NodeId& new_parent, |
68 const NodeId& old_parent, | 45 const NodeId& old_parent, |
69 int32_t change_id) { | 46 int32_t change_id) { |
70 client()->OnNodeHierarchyChanged(NodeIdToTransportId(node), | 47 client()->OnNodeHierarchyChanged(NodeIdToTransportId(node), |
71 NodeIdToTransportId(new_parent), | 48 NodeIdToTransportId(new_parent), |
72 NodeIdToTransportId(old_parent), | 49 NodeIdToTransportId(old_parent), |
73 change_id); | 50 change_id); |
74 } | 51 } |
75 | 52 |
76 void ViewManagerConnection::NotifyNodeViewReplaced(const NodeId& node, | |
77 const ViewId& new_view_id, | |
78 const ViewId& old_view_id, | |
79 int32_t change_id) { | |
80 client()->OnNodeViewReplaced(NodeIdToTransportId(node), | |
81 ViewIdToTransportId(new_view_id), | |
82 ViewIdToTransportId(old_view_id), | |
83 change_id); | |
84 } | |
85 | |
86 bool ViewManagerConnection::DeleteNodeImpl(ViewManagerConnection* source, | |
87 const NodeId& node_id, | |
88 int32_t change_id) { | |
89 DCHECK_EQ(node_id.connection_id, id_); | |
90 Node* node = GetNode(node_id); | |
91 if (!node) | |
92 return false; | |
93 RootNodeManager::ScopedChange change(source, context(), change_id); | |
94 if (node->GetParent()) | |
95 node->GetParent()->Remove(node); | |
96 std::vector<Node*> children(node->GetChildren()); | |
97 for (size_t i = 0; i < children.size(); ++i) | |
98 node->Remove(children[i]); | |
99 DCHECK(node->GetChildren().empty()); | |
100 node_map_.erase(node_id.node_id); | |
101 delete node; | |
102 return true; | |
103 } | |
104 | |
105 bool ViewManagerConnection::DeleteViewImpl(ViewManagerConnection* source, | |
106 const ViewId& view_id, | |
107 int32_t change_id) { | |
108 DCHECK_EQ(view_id.connection_id, id_); | |
109 View* view = GetView(view_id); | |
110 if (!view) | |
111 return false; | |
112 RootNodeManager::ScopedChange change(source, context(), change_id); | |
113 if (view->node()) | |
114 view->node()->SetView(NULL); | |
115 view_map_.erase(view_id.view_id); | |
116 delete view; | |
117 return true; | |
118 } | |
119 | |
120 bool ViewManagerConnection::SetViewImpl(const NodeId& node_id, | |
121 const ViewId& view_id, | |
122 int32_t change_id) { | |
123 Node* node = GetNode(node_id); | |
124 if (!node) | |
125 return false; | |
126 View* view = GetView(view_id); | |
127 if (!view && view_id != ViewId()) | |
128 return false; | |
129 RootNodeManager::ScopedChange change(this, context(), change_id); | |
130 node->SetView(view); | |
131 return true; | |
132 } | |
133 | |
134 void ViewManagerConnection::CreateNode( | 53 void ViewManagerConnection::CreateNode( |
135 uint16_t node_id, | 54 uint16_t node_id, |
136 const Callback<void(bool)>& callback) { | 55 const Callback<void(bool)>& callback) { |
137 // Negative values are reserved. | 56 // Negative values are reserved. |
138 if (node_map_.find(node_id) != node_map_.end()) { | 57 if (node_map_.find(node_id) != node_map_.end()) { |
139 callback.Run(false); | 58 callback.Run(false); |
140 return; | 59 return; |
141 } | 60 } |
142 node_map_[node_id] = new Node(this, NodeId(id_, node_id)); | 61 node_map_[node_id] = new Node(this, NodeId(id_, node_id)); |
143 callback.Run(true); | 62 callback.Run(true); |
144 } | 63 } |
145 | 64 |
146 void ViewManagerConnection::DeleteNode( | |
147 uint32_t transport_node_id, | |
148 int32_t change_id, | |
149 const mojo::Callback<void(bool)>& callback) { | |
150 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | |
151 ViewManagerConnection* connection = context()->GetConnection( | |
152 node_id.connection_id); | |
153 callback.Run(connection && | |
154 connection->DeleteNodeImpl(this, node_id, change_id)); | |
155 } | |
156 | |
157 void ViewManagerConnection::AddNode( | 65 void ViewManagerConnection::AddNode( |
158 uint32_t parent_id, | 66 uint32_t parent_id, |
159 uint32_t child_id, | 67 uint32_t child_id, |
160 int32_t change_id, | 68 int32_t change_id, |
161 const Callback<void(bool)>& callback) { | 69 const Callback<void(bool)>& callback) { |
162 Node* parent = GetNode(NodeIdFromTransportId(parent_id)); | 70 Node* parent = GetNode(NodeIdFromTransportId(parent_id)); |
163 Node* child = GetNode(NodeIdFromTransportId(child_id)); | 71 Node* child = GetNode(NodeIdFromTransportId(child_id)); |
164 const bool success = parent && child && parent != child; | 72 const bool success = parent && child && parent != child; |
165 if (success) { | 73 if (success) { |
166 RootNodeManager::ScopedChange change(this, context(), change_id); | 74 RootNodeManager::ScopedChange change(this, context(), change_id); |
167 parent->Add(child); | 75 parent->Add(child); |
168 } | 76 } |
169 callback.Run(success); | 77 callback.Run(success); |
170 } | 78 } |
171 | 79 |
172 void ViewManagerConnection::RemoveNodeFromParent( | 80 void ViewManagerConnection::RemoveNodeFromParent( |
173 uint32_t node_id, | 81 uint32_t node_id, |
174 int32_t change_id, | 82 int32_t change_id, |
175 const Callback<void(bool)>& callback) { | 83 const Callback<void(bool)>& callback) { |
176 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 84 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
177 const bool success = (node && node->GetParent()); | 85 const bool success = (node && node->GetParent()); |
178 if (success) { | 86 if (success) { |
179 RootNodeManager::ScopedChange change(this, context(), change_id); | 87 RootNodeManager::ScopedChange change(this, context(), change_id); |
180 node->GetParent()->Remove(node); | 88 node->GetParent()->Remove(node); |
181 } | 89 } |
182 callback.Run(success); | 90 callback.Run(success); |
183 } | 91 } |
184 | 92 |
185 void ViewManagerConnection::CreateView( | |
186 uint16_t view_id, | |
187 const mojo::Callback<void(bool)>& callback) { | |
188 if (view_map_.count(view_id)) { | |
189 callback.Run(false); | |
190 return; | |
191 } | |
192 view_map_[view_id] = new View(ViewId(id_, view_id)); | |
193 callback.Run(true); | |
194 } | |
195 | |
196 void ViewManagerConnection::DeleteView( | |
197 uint32_t transport_view_id, | |
198 int32_t change_id, | |
199 const mojo::Callback<void(bool)>& callback) OVERRIDE { | |
200 const ViewId view_id(ViewIdFromTransportId(transport_view_id)); | |
201 ViewManagerConnection* connection = context()->GetConnection( | |
202 view_id.connection_id); | |
203 callback.Run(connection && | |
204 connection->DeleteViewImpl(this, view_id, change_id)); | |
205 } | |
206 | |
207 void ViewManagerConnection::SetView( | |
208 uint32_t transport_node_id, | |
209 uint32_t transport_view_id, | |
210 int32_t change_id, | |
211 const mojo::Callback<void(bool)>& callback) { | |
212 const NodeId node_id(NodeIdFromTransportId(transport_node_id)); | |
213 callback.Run(SetViewImpl(node_id, ViewIdFromTransportId(transport_view_id), | |
214 change_id)); | |
215 } | |
216 | |
217 void ViewManagerConnection::OnNodeHierarchyChanged(const NodeId& node, | 93 void ViewManagerConnection::OnNodeHierarchyChanged(const NodeId& node, |
218 const NodeId& new_parent, | 94 const NodeId& new_parent, |
219 const NodeId& old_parent) { | 95 const NodeId& old_parent) { |
220 context()->NotifyNodeHierarchyChanged(node, new_parent, old_parent); | 96 context()->NotifyNodeHierarchyChanged(node, new_parent, old_parent); |
221 } | 97 } |
222 | 98 |
223 void ViewManagerConnection::OnNodeViewReplaced(const NodeId& node, | |
224 const ViewId& new_view_id, | |
225 const ViewId& old_view_id) { | |
226 context()->NotifyNodeViewReplaced(node, new_view_id, old_view_id); | |
227 } | |
228 | |
229 } // namespace view_manager | 99 } // namespace view_manager |
230 } // namespace services | 100 } // namespace services |
231 } // namespace mojo | 101 } // namespace mojo |
OLD | NEW |