Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: dbus/object_manager.cc

Issue 12491014: Support D-Bus Object Manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comments Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(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 (size_t i = 0; i < interface_names.size(); ++i)
195 RemoveInterface(object_path, interface_names[i]);
196 }
197
198 void ObjectManager::InterfacesRemovedConnected(
199 const std::string& interface_name,
200 const std::string& signal_name,
201 bool success) {
202 LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value()
203 << ": Failed to connect to "
204 << "InterfacesRemoved signal.";
205 }
206
207 void ObjectManager::UpdateObject(const ObjectPath& object_path,
208 MessageReader* reader) {
209 DCHECK(reader);
210 MessageReader array_reader(NULL);
211 if (!reader->PopArray(&array_reader))
212 return;
213
214 while (array_reader.HasMoreData()) {
215 MessageReader dict_entry_reader(NULL);
216 std::string interface_name;
217 if (!array_reader.PopDictEntry(&dict_entry_reader) ||
218 !dict_entry_reader.PopString(&interface_name))
219 continue;
220
221 AddInterface(object_path, interface_name, &dict_entry_reader);
222 }
223 }
224
225
226 void ObjectManager::AddInterface(const ObjectPath& object_path,
227 const std::string& interface_name,
228 MessageReader* reader) {
229 InterfaceMap::iterator iiter = interface_map_.find(interface_name);
230 if (iiter == interface_map_.end())
231 return;
232 Interface* interface = iiter->second;
233
234 ObjectMap::iterator oiter = object_map_.find(object_path);
235 Object* object;
236 if (oiter == object_map_.end()) {
237 object = object_map_[object_path] = new Object;
238 object->object_proxy = bus_->GetObjectProxy(service_name_, object_path);
239 } else
240 object = oiter->second;
241
242 Object::PropertiesMap::iterator piter =
243 object->properties_map.find(interface_name);
244 PropertySet* property_set;
245 const bool interface_added = (piter == object->properties_map.end());
246 if (interface_added) {
247 property_set = object->properties_map[interface_name] =
248 interface->CreateProperties(object->object_proxy,
249 object_path, interface_name);
250 property_set->ConnectSignals();
251 } else
252 property_set = piter->second;
253
254 property_set->UpdatePropertiesFromReader(reader);
255
256 if (interface_added)
257 interface->ObjectAdded(object_path, interface_name);
258 }
259
260 void ObjectManager::RemoveInterface(const ObjectPath& object_path,
261 const std::string& interface_name) {
262 ObjectMap::iterator oiter = object_map_.find(object_path);
263 if (oiter == object_map_.end())
264 return;
265 Object* object = oiter->second;
266
267 Object::PropertiesMap::iterator piter =
268 object->properties_map.find(interface_name);
269 if (piter == object->properties_map.end())
270 return;
271
272 // Inform the interface before removing the properties structure or object
273 // in case it needs details from them to make its own decisions.
274 InterfaceMap::iterator iiter = interface_map_.find(interface_name);
275 if (iiter != interface_map_.end()) {
276 Interface* interface = iiter->second;
277 interface->ObjectRemoved(object_path, interface_name);
278 }
279
280 object->properties_map.erase(piter);
281
282 if (object->properties_map.empty()) {
283 object_map_.erase(oiter);
284 delete object;
285 }
286 }
287
288 } // namespace dbus
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698