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" |
10 | 11 |
11 namespace mojo { | 12 namespace mojo { |
12 namespace services { | 13 namespace services { |
13 namespace view_manager { | 14 namespace view_manager { |
14 | 15 |
15 ViewManagerConnection::ViewManagerConnection() : id_(0) { | 16 ViewManagerConnection::ViewManagerConnection() : id_(0) { |
16 } | 17 } |
17 | 18 |
18 ViewManagerConnection::~ViewManagerConnection() { | 19 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 |
19 STLDeleteContainerPairSecondPointers(node_map_.begin(), node_map_.end()); | 34 STLDeleteContainerPairSecondPointers(node_map_.begin(), node_map_.end()); |
20 context()->RemoveConnection(this); | 35 context()->RemoveConnection(this); |
21 } | 36 } |
22 | 37 |
23 void ViewManagerConnection::Initialize( | 38 void ViewManagerConnection::Initialize( |
24 ServiceConnector<ViewManagerConnection, RootNodeManager>* service_factory, | 39 ServiceConnector<ViewManagerConnection, RootNodeManager>* service_factory, |
25 ScopedMessagePipeHandle client_handle) { | 40 ScopedMessagePipeHandle client_handle) { |
26 DCHECK_EQ(0, id_); // Should only get Initialize() once. | 41 DCHECK_EQ(0, id_); // Should only get Initialize() once. |
27 ServiceConnection<ViewManager, ViewManagerConnection, RootNodeManager>:: | 42 ServiceConnection<ViewManager, ViewManagerConnection, RootNodeManager>:: |
28 Initialize(service_factory, client_handle.Pass()); | 43 Initialize(service_factory, client_handle.Pass()); |
29 id_ = context()->GetAndAdvanceNextConnectionId(); | 44 id_ = context()->GetAndAdvanceNextConnectionId(); |
30 context()->AddConnection(this); | 45 context()->AddConnection(this); |
31 client()->OnConnectionEstablished(id_); | 46 client()->OnConnectionEstablished(id_); |
32 } | 47 } |
33 | 48 |
34 Node* ViewManagerConnection::GetNode(const NodeId& id) { | 49 Node* ViewManagerConnection::GetNode(const NodeId& id) { |
35 if (id_ == id.connection_id) { | 50 if (id_ == id.connection_id) { |
36 NodeMap::iterator i = node_map_.find(id.node_id); | 51 NodeMap::iterator i = node_map_.find(id.node_id); |
37 return i == node_map_.end() ? NULL : i->second; | 52 return i == node_map_.end() ? NULL : i->second; |
38 } | 53 } |
39 return context()->GetNode(id); | 54 return context()->GetNode(id); |
40 } | 55 } |
41 | 56 |
| 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 |
42 void ViewManagerConnection::NotifyNodeHierarchyChanged( | 65 void ViewManagerConnection::NotifyNodeHierarchyChanged( |
43 const NodeId& node, | 66 const NodeId& node, |
44 const NodeId& new_parent, | 67 const NodeId& new_parent, |
45 const NodeId& old_parent, | 68 const NodeId& old_parent, |
46 int32_t change_id) { | 69 int32_t change_id) { |
47 client()->OnNodeHierarchyChanged(NodeIdToTransportId(node), | 70 client()->OnNodeHierarchyChanged(NodeIdToTransportId(node), |
48 NodeIdToTransportId(new_parent), | 71 NodeIdToTransportId(new_parent), |
49 NodeIdToTransportId(old_parent), | 72 NodeIdToTransportId(old_parent), |
50 change_id); | 73 change_id); |
51 } | 74 } |
52 | 75 |
| 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 |
53 void ViewManagerConnection::CreateNode( | 134 void ViewManagerConnection::CreateNode( |
54 uint16_t node_id, | 135 uint16_t node_id, |
55 const Callback<void(bool)>& callback) { | 136 const Callback<void(bool)>& callback) { |
56 // Negative values are reserved. | 137 // Negative values are reserved. |
57 if (node_map_.find(node_id) != node_map_.end()) { | 138 if (node_map_.find(node_id) != node_map_.end()) { |
58 callback.Run(false); | 139 callback.Run(false); |
59 return; | 140 return; |
60 } | 141 } |
61 node_map_[node_id] = new Node(this, NodeId(id_, node_id)); | 142 node_map_[node_id] = new Node(this, NodeId(id_, node_id)); |
62 callback.Run(true); | 143 callback.Run(true); |
63 } | 144 } |
64 | 145 |
| 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 |
65 void ViewManagerConnection::AddNode( | 157 void ViewManagerConnection::AddNode( |
66 uint32_t parent_id, | 158 uint32_t parent_id, |
67 uint32_t child_id, | 159 uint32_t child_id, |
68 int32_t change_id, | 160 int32_t change_id, |
69 const Callback<void(bool)>& callback) { | 161 const Callback<void(bool)>& callback) { |
70 Node* parent = GetNode(NodeIdFromTransportId(parent_id)); | 162 Node* parent = GetNode(NodeIdFromTransportId(parent_id)); |
71 Node* child = GetNode(NodeIdFromTransportId(child_id)); | 163 Node* child = GetNode(NodeIdFromTransportId(child_id)); |
72 const bool success = parent && child && parent != child; | 164 const bool success = parent && child && parent != child; |
73 if (success) { | 165 if (success) { |
74 RootNodeManager::ScopedChange change(this, context(), change_id); | 166 RootNodeManager::ScopedChange change(this, context(), change_id); |
75 parent->Add(child); | 167 parent->Add(child); |
76 } | 168 } |
77 callback.Run(success); | 169 callback.Run(success); |
78 } | 170 } |
79 | 171 |
80 void ViewManagerConnection::RemoveNodeFromParent( | 172 void ViewManagerConnection::RemoveNodeFromParent( |
81 uint32_t node_id, | 173 uint32_t node_id, |
82 int32_t change_id, | 174 int32_t change_id, |
83 const Callback<void(bool)>& callback) { | 175 const Callback<void(bool)>& callback) { |
84 Node* node = GetNode(NodeIdFromTransportId(node_id)); | 176 Node* node = GetNode(NodeIdFromTransportId(node_id)); |
85 const bool success = (node && node->GetParent()); | 177 const bool success = (node && node->GetParent()); |
86 if (success) { | 178 if (success) { |
87 RootNodeManager::ScopedChange change(this, context(), change_id); | 179 RootNodeManager::ScopedChange change(this, context(), change_id); |
88 node->GetParent()->Remove(node); | 180 node->GetParent()->Remove(node); |
89 } | 181 } |
90 callback.Run(success); | 182 callback.Run(success); |
91 } | 183 } |
92 | 184 |
| 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) { |
| 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 |
93 void ViewManagerConnection::OnNodeHierarchyChanged(const NodeId& node, | 217 void ViewManagerConnection::OnNodeHierarchyChanged(const NodeId& node, |
94 const NodeId& new_parent, | 218 const NodeId& new_parent, |
95 const NodeId& old_parent) { | 219 const NodeId& old_parent) { |
96 context()->NotifyNodeHierarchyChanged(node, new_parent, old_parent); | 220 context()->NotifyNodeHierarchyChanged(node, new_parent, old_parent); |
97 } | 221 } |
98 | 222 |
| 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 |
99 } // namespace view_manager | 229 } // namespace view_manager |
100 } // namespace services | 230 } // namespace services |
101 } // namespace mojo | 231 } // namespace mojo |
OLD | NEW |