OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2013 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 "dbus/object_manager.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/logging.h" | |
9 #include "dbus/bus.h" | |
10 #include "dbus/message.h" | |
11 #include "dbus/object_proxy.h" | |
12 #include "dbus/property.h" | |
13 | |
14 namespace dbus { | |
15 | |
16 ObjectManager::ObjectManager(Bus* bus, | |
17 const std::string& service_name, | |
18 const ObjectPath& object_path) | |
19 : bus_(bus), | |
20 service_name_(service_name), | |
21 object_path_(object_path), | |
22 weak_ptr_factory_(this) { | |
23 DVLOG(1) << "Creating ObjectManager for " << service_name_ | |
24 << " " << object_path_.value(); | |
25 | |
26 DCHECK(bus_); | |
27 object_proxy_ = bus_->GetObjectProxy(service_name_, object_path_); | |
28 | |
29 object_proxy_->ConnectToSignal( | |
30 kObjectManagerInterface, | |
31 kObjectManagerInterfacesAdded, | |
32 base::Bind(&ObjectManager::InterfacesAddedReceived, | |
33 weak_ptr_factory_.GetWeakPtr()), | |
34 base::Bind(&ObjectManager::InterfacesAddedConnected, | |
35 weak_ptr_factory_.GetWeakPtr())); | |
36 | |
37 object_proxy_->ConnectToSignal( | |
38 kObjectManagerInterface, | |
39 kObjectManagerInterfacesRemoved, | |
40 base::Bind(&ObjectManager::InterfacesRemovedReceived, | |
41 weak_ptr_factory_.GetWeakPtr()), | |
42 base::Bind(&ObjectManager::InterfacesRemovedConnected, | |
43 weak_ptr_factory_.GetWeakPtr())); | |
44 | |
45 GetManagedObjects(); | |
46 } | |
47 | |
48 ObjectManager::~ObjectManager() { | |
49 // Clean up Object structures | |
50 for (ObjectMap::iterator iter = object_map_.begin(); | |
51 iter != object_map_.end(); ++iter) { | |
52 Object* object = iter->second; | |
53 | |
54 for (Object::PropertiesMap::iterator piter = object->properties_map.begin(); | |
55 piter != object->properties_map.end(); ++piter) { | |
56 PropertySet* properties = piter->second; | |
57 delete properties; | |
58 } | |
59 | |
60 delete object; | |
61 } | |
62 } | |
63 | |
64 void ObjectManager::RegisterInterface(const std::string& interface_name, | |
65 Interface* interface) { | |
66 interface_map_[interface_name] = interface; | |
67 } | |
68 | |
69 void ObjectManager::UnregisterInterface(const std::string& interface_name) { | |
70 InterfaceMap::iterator iter = interface_map_.find(interface_name); | |
71 if (iter != interface_map_.end()) | |
72 interface_map_.erase(iter); | |
73 } | |
74 | |
75 std::vector<ObjectPath> ObjectManager::GetObjects() { | |
76 std::vector<ObjectPath> object_paths; | |
77 | |
78 for (ObjectMap::iterator iter = object_map_.begin(); | |
79 iter != object_map_.end(); ++iter) | |
80 object_paths.push_back(iter->first); | |
81 | |
82 return object_paths; | |
83 } | |
84 | |
85 std::vector<ObjectPath> ObjectManager::GetObjectsWithInterface( | |
86 const std::string& interface_name) { | |
87 std::vector<ObjectPath> object_paths; | |
88 | |
89 for (ObjectMap::iterator oiter = object_map_.begin(); | |
90 oiter != object_map_.end(); ++oiter) { | |
91 Object* object = oiter->second; | |
92 | |
93 Object::PropertiesMap::iterator piter = | |
94 object->properties_map.find(interface_name); | |
95 if (piter != object->properties_map.end()) | |
96 object_paths.push_back(oiter->first); | |
97 } | |
98 | |
99 return object_paths; | |
100 } | |
101 | |
102 ObjectProxy* ObjectManager::GetObjectProxy(const ObjectPath& object_path) { | |
103 ObjectMap::iterator iter = object_map_.find(object_path); | |
104 if (iter == object_map_.end()) | |
105 return NULL; | |
106 | |
107 Object* object = iter->second; | |
108 return object->object_proxy; | |
109 } | |
110 | |
111 PropertySet* ObjectManager::GetProperties(const ObjectPath& object_path, | |
112 const std::string& interface_name) { | |
113 ObjectMap::iterator iter = object_map_.find(object_path); | |
114 if (iter == object_map_.end()) | |
115 return NULL; | |
116 | |
117 Object* object = iter->second; | |
118 Object::PropertiesMap::iterator piter = | |
119 object->properties_map.find(interface_name); | |
120 if (piter == object->properties_map.end()) | |
121 return NULL; | |
122 | |
123 return piter->second; | |
124 } | |
125 | |
126 void ObjectManager::GetManagedObjects() { | |
127 MethodCall method_call(kObjectManagerInterface, | |
128 kObjectManagerGetManagedObjects); | |
129 | |
130 object_proxy_->CallMethod( | |
131 &method_call, | |
132 ObjectProxy::TIMEOUT_USE_DEFAULT, | |
133 base::Bind(&ObjectManager::OnGetManagedObjects, | |
134 weak_ptr_factory_.GetWeakPtr())); | |
135 } | |
136 | |
137 void ObjectManager::OnGetManagedObjects(Response* response) { | |
138 if (response != NULL) { | |
139 MessageReader reader(response); | |
140 MessageReader array_reader(NULL); | |
141 if (!reader.PopArray(&array_reader)) | |
142 return; | |
143 | |
144 while (array_reader.HasMoreData()) { | |
145 MessageReader dict_entry_reader(NULL); | |
146 ObjectPath object_path; | |
147 if (!array_reader.PopDictEntry(&dict_entry_reader) || | |
148 !dict_entry_reader.PopObjectPath(&object_path)) | |
149 continue; | |
150 | |
151 UpdateObject(object_path, &dict_entry_reader); | |
152 } | |
153 | |
154 } else { | |
155 LOG(WARNING) << service_name_ << " " << object_path_.value() | |
156 << ": Failed to get managed objects"; | |
157 } | |
158 } | |
159 | |
160 void ObjectManager::InterfacesAddedReceived(Signal* signal) { | |
161 DCHECK(signal); | |
162 MessageReader reader(signal); | |
163 ObjectPath object_path; | |
164 if (!reader.PopObjectPath(&object_path)) { | |
165 LOG(WARNING) << service_name_ << " " << object_path_.value() | |
166 << ": InterfacesAdded signal has incorrect parameters: " | |
167 << signal->ToString(); | |
168 return; | |
169 } | |
170 | |
171 UpdateObject(object_path, &reader); | |
172 } | |
173 | |
174 void ObjectManager::InterfacesAddedConnected(const std::string& interface_name, | |
175 const std::string& signal_name, | |
176 bool success) { | |
177 LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value() | |
178 << ": Failed to connect to InterfacesAdded signal."; | |
179 } | |
180 | |
181 void ObjectManager::InterfacesRemovedReceived(Signal* signal) { | |
182 DCHECK(signal); | |
183 MessageReader reader(signal); | |
184 ObjectPath object_path; | |
185 std::vector<std::string> interface_names; | |
186 if (!reader.PopObjectPath(&object_path) || | |
187 !reader.PopArrayOfStrings(&interface_names)) { | |
188 LOG(WARNING) << service_name_ << " " << object_path_.value() | |
189 << ": InterfacesRemoved signal has incorrect parameters: " | |
190 << signal->ToString(); | |
191 return; | |
192 } | |
193 | |
194 for (std::vector<std::string>::const_iterator it = interface_names.begin(); | |
195 it != interface_names.end(); ++it) | |
satorux1
2013/03/21 05:45:43
matter of taste: for (size_t i = 0; ...) is more s
keybuk
2013/03/21 17:50:00
Done.
| |
196 RemoveInterface(object_path, *it); | |
197 } | |
198 | |
199 void ObjectManager::InterfacesRemovedConnected( | |
200 const std::string& interface_name, | |
201 const std::string& signal_name, | |
202 bool success) { | |
203 LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value() | |
204 << ": Failed to connect to " | |
205 << "InterfacesRemoved signal."; | |
206 } | |
207 | |
208 void ObjectManager::UpdateObject(const ObjectPath& object_path, | |
209 MessageReader* reader) { | |
210 DCHECK(reader); | |
211 MessageReader array_reader(NULL); | |
212 if (!reader->PopArray(&array_reader)) | |
213 return; | |
214 | |
215 while (array_reader.HasMoreData()) { | |
216 MessageReader dict_entry_reader(NULL); | |
217 std::string interface_name; | |
218 if (!array_reader.PopDictEntry(&dict_entry_reader) || | |
219 !dict_entry_reader.PopString(&interface_name)) | |
220 continue; | |
221 | |
222 AddInterface(object_path, interface_name, &dict_entry_reader); | |
223 } | |
224 } | |
225 | |
226 | |
227 void ObjectManager::AddInterface(const ObjectPath& object_path, | |
228 const std::string& interface_name, | |
229 MessageReader* reader) { | |
230 InterfaceMap::iterator iiter = interface_map_.find(interface_name); | |
231 if (iiter == interface_map_.end()) | |
232 return; | |
233 Interface* interface = iiter->second; | |
234 | |
235 ObjectMap::iterator oiter = object_map_.find(object_path); | |
236 Object* object; | |
237 if (oiter == object_map_.end()) { | |
238 object = object_map_[object_path] = new Object; | |
239 object->object_proxy = bus_->GetObjectProxy(service_name_, object_path); | |
240 } else | |
241 object = oiter->second; | |
242 | |
243 Object::PropertiesMap::iterator piter = | |
244 object->properties_map.find(interface_name); | |
245 PropertySet* property_set; | |
246 const bool interface_added = (piter == object->properties_map.end()); | |
247 if (interface_added) { | |
248 property_set = object->properties_map[interface_name] = | |
249 interface->CreateProperties(object->object_proxy, | |
250 object_path, interface_name); | |
251 property_set->ConnectSignals(); | |
252 } else | |
253 property_set = piter->second; | |
254 | |
255 property_set->UpdatePropertiesFromReader(reader); | |
256 | |
257 if (interface_added) | |
258 interface->ObjectAdded(object_path, interface_name); | |
259 } | |
260 | |
261 void ObjectManager::RemoveInterface(const ObjectPath& object_path, | |
262 const std::string& interface_name) { | |
263 ObjectMap::iterator oiter = object_map_.find(object_path); | |
264 if (oiter == object_map_.end()) | |
265 return; | |
266 Object* object = oiter->second; | |
267 | |
268 Object::PropertiesMap::iterator piter = | |
269 object->properties_map.find(interface_name); | |
270 if (piter == object->properties_map.end()) | |
271 return; | |
272 | |
273 // Inform the interface before removing the properties structure or object | |
274 // in case it needs details from them to make its own decisions. | |
275 InterfaceMap::iterator iiter = interface_map_.find(interface_name); | |
276 if (iiter != interface_map_.end()) { | |
277 Interface* interface = iiter->second; | |
278 interface->ObjectRemoved(object_path, interface_name); | |
279 } | |
280 | |
281 object->properties_map.erase(piter); | |
282 | |
283 if (object->properties_map.empty()) { | |
284 object_map_.erase(oiter); | |
285 delete object; | |
286 } | |
287 } | |
288 | |
289 } // namespace dbus | |
OLD | NEW |