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.
5 #include "dbus/object_manager.h"
8 #include "base/logging.h"
10 #include "dbus/message.h"
11 #include "dbus/object_proxy.h"
12 #include "dbus/property.h"
16 ObjectManager::Object::Object()
17 : object_proxy(NULL
) {
20 ObjectManager::Object::~Object() {
23 ObjectManager::ObjectManager(Bus
* bus
,
24 const std::string
& service_name
,
25 const ObjectPath
& object_path
)
27 service_name_(service_name
),
28 object_path_(object_path
),
29 weak_ptr_factory_(this) {
30 DVLOG(1) << "Creating ObjectManager for " << service_name_
31 << " " << object_path_
.value();
34 object_proxy_
= bus_
->GetObjectProxy(service_name_
, object_path_
);
35 object_proxy_
->SetNameOwnerChangedCallback(
36 base::Bind(&ObjectManager::NameOwnerChanged
,
37 weak_ptr_factory_
.GetWeakPtr()));
39 object_proxy_
->ConnectToSignal(
40 kObjectManagerInterface
,
41 kObjectManagerInterfacesAdded
,
42 base::Bind(&ObjectManager::InterfacesAddedReceived
,
43 weak_ptr_factory_
.GetWeakPtr()),
44 base::Bind(&ObjectManager::InterfacesAddedConnected
,
45 weak_ptr_factory_
.GetWeakPtr()));
47 object_proxy_
->ConnectToSignal(
48 kObjectManagerInterface
,
49 kObjectManagerInterfacesRemoved
,
50 base::Bind(&ObjectManager::InterfacesRemovedReceived
,
51 weak_ptr_factory_
.GetWeakPtr()),
52 base::Bind(&ObjectManager::InterfacesRemovedConnected
,
53 weak_ptr_factory_
.GetWeakPtr()));
58 ObjectManager::~ObjectManager() {
59 // Clean up Object structures
60 for (ObjectMap::iterator iter
= object_map_
.begin();
61 iter
!= object_map_
.end(); ++iter
) {
62 Object
* object
= iter
->second
;
64 for (Object::PropertiesMap::iterator piter
= object
->properties_map
.begin();
65 piter
!= object
->properties_map
.end(); ++piter
) {
66 PropertySet
* properties
= piter
->second
;
74 void ObjectManager::RegisterInterface(const std::string
& interface_name
,
75 Interface
* interface
) {
76 interface_map_
[interface_name
] = interface
;
79 void ObjectManager::UnregisterInterface(const std::string
& interface_name
) {
80 InterfaceMap::iterator iter
= interface_map_
.find(interface_name
);
81 if (iter
!= interface_map_
.end())
82 interface_map_
.erase(iter
);
85 std::vector
<ObjectPath
> ObjectManager::GetObjects() {
86 std::vector
<ObjectPath
> object_paths
;
88 for (ObjectMap::iterator iter
= object_map_
.begin();
89 iter
!= object_map_
.end(); ++iter
)
90 object_paths
.push_back(iter
->first
);
95 std::vector
<ObjectPath
> ObjectManager::GetObjectsWithInterface(
96 const std::string
& interface_name
) {
97 std::vector
<ObjectPath
> object_paths
;
99 for (ObjectMap::iterator oiter
= object_map_
.begin();
100 oiter
!= object_map_
.end(); ++oiter
) {
101 Object
* object
= oiter
->second
;
103 Object::PropertiesMap::iterator piter
=
104 object
->properties_map
.find(interface_name
);
105 if (piter
!= object
->properties_map
.end())
106 object_paths
.push_back(oiter
->first
);
112 ObjectProxy
* ObjectManager::GetObjectProxy(const ObjectPath
& object_path
) {
113 ObjectMap::iterator iter
= object_map_
.find(object_path
);
114 if (iter
== object_map_
.end())
117 Object
* object
= iter
->second
;
118 return object
->object_proxy
;
121 PropertySet
* ObjectManager::GetProperties(const ObjectPath
& object_path
,
122 const std::string
& interface_name
) {
123 ObjectMap::iterator iter
= object_map_
.find(object_path
);
124 if (iter
== object_map_
.end())
127 Object
* object
= iter
->second
;
128 Object::PropertiesMap::iterator piter
=
129 object
->properties_map
.find(interface_name
);
130 if (piter
== object
->properties_map
.end())
133 return piter
->second
;
136 void ObjectManager::GetManagedObjects() {
137 MethodCall
method_call(kObjectManagerInterface
,
138 kObjectManagerGetManagedObjects
);
140 object_proxy_
->CallMethod(
142 ObjectProxy::TIMEOUT_USE_DEFAULT
,
143 base::Bind(&ObjectManager::OnGetManagedObjects
,
144 weak_ptr_factory_
.GetWeakPtr()));
147 void ObjectManager::OnGetManagedObjects(Response
* response
) {
148 if (response
!= NULL
) {
149 MessageReader
reader(response
);
150 MessageReader
array_reader(NULL
);
151 if (!reader
.PopArray(&array_reader
))
154 while (array_reader
.HasMoreData()) {
155 MessageReader
dict_entry_reader(NULL
);
156 ObjectPath object_path
;
157 if (!array_reader
.PopDictEntry(&dict_entry_reader
) ||
158 !dict_entry_reader
.PopObjectPath(&object_path
))
161 UpdateObject(object_path
, &dict_entry_reader
);
165 LOG(WARNING
) << service_name_
<< " " << object_path_
.value()
166 << ": Failed to get managed objects";
170 void ObjectManager::InterfacesAddedReceived(Signal
* signal
) {
172 MessageReader
reader(signal
);
173 ObjectPath object_path
;
174 if (!reader
.PopObjectPath(&object_path
)) {
175 LOG(WARNING
) << service_name_
<< " " << object_path_
.value()
176 << ": InterfacesAdded signal has incorrect parameters: "
177 << signal
->ToString();
181 UpdateObject(object_path
, &reader
);
184 void ObjectManager::InterfacesAddedConnected(const std::string
& interface_name
,
185 const std::string
& signal_name
,
187 LOG_IF(WARNING
, !success
) << service_name_
<< " " << object_path_
.value()
188 << ": Failed to connect to InterfacesAdded signal.";
191 void ObjectManager::InterfacesRemovedReceived(Signal
* signal
) {
193 MessageReader
reader(signal
);
194 ObjectPath object_path
;
195 std::vector
<std::string
> interface_names
;
196 if (!reader
.PopObjectPath(&object_path
) ||
197 !reader
.PopArrayOfStrings(&interface_names
)) {
198 LOG(WARNING
) << service_name_
<< " " << object_path_
.value()
199 << ": InterfacesRemoved signal has incorrect parameters: "
200 << signal
->ToString();
204 for (size_t i
= 0; i
< interface_names
.size(); ++i
)
205 RemoveInterface(object_path
, interface_names
[i
]);
208 void ObjectManager::InterfacesRemovedConnected(
209 const std::string
& interface_name
,
210 const std::string
& signal_name
,
212 LOG_IF(WARNING
, !success
) << service_name_
<< " " << object_path_
.value()
213 << ": Failed to connect to "
214 << "InterfacesRemoved signal.";
217 void ObjectManager::UpdateObject(const ObjectPath
& object_path
,
218 MessageReader
* reader
) {
220 MessageReader
array_reader(NULL
);
221 if (!reader
->PopArray(&array_reader
))
224 while (array_reader
.HasMoreData()) {
225 MessageReader
dict_entry_reader(NULL
);
226 std::string interface_name
;
227 if (!array_reader
.PopDictEntry(&dict_entry_reader
) ||
228 !dict_entry_reader
.PopString(&interface_name
))
231 AddInterface(object_path
, interface_name
, &dict_entry_reader
);
236 void ObjectManager::AddInterface(const ObjectPath
& object_path
,
237 const std::string
& interface_name
,
238 MessageReader
* reader
) {
239 InterfaceMap::iterator iiter
= interface_map_
.find(interface_name
);
240 if (iiter
== interface_map_
.end())
242 Interface
* interface
= iiter
->second
;
244 ObjectMap::iterator oiter
= object_map_
.find(object_path
);
246 if (oiter
== object_map_
.end()) {
247 object
= object_map_
[object_path
] = new Object
;
248 object
->object_proxy
= bus_
->GetObjectProxy(service_name_
, object_path
);
250 object
= oiter
->second
;
252 Object::PropertiesMap::iterator piter
=
253 object
->properties_map
.find(interface_name
);
254 PropertySet
* property_set
;
255 const bool interface_added
= (piter
== object
->properties_map
.end());
256 if (interface_added
) {
257 property_set
= object
->properties_map
[interface_name
] =
258 interface
->CreateProperties(object
->object_proxy
,
259 object_path
, interface_name
);
260 property_set
->ConnectSignals();
262 property_set
= piter
->second
;
264 property_set
->UpdatePropertiesFromReader(reader
);
267 interface
->ObjectAdded(object_path
, interface_name
);
270 void ObjectManager::RemoveInterface(const ObjectPath
& object_path
,
271 const std::string
& interface_name
) {
272 ObjectMap::iterator oiter
= object_map_
.find(object_path
);
273 if (oiter
== object_map_
.end())
275 Object
* object
= oiter
->second
;
277 Object::PropertiesMap::iterator piter
=
278 object
->properties_map
.find(interface_name
);
279 if (piter
== object
->properties_map
.end())
282 // Inform the interface before removing the properties structure or object
283 // in case it needs details from them to make its own decisions.
284 InterfaceMap::iterator iiter
= interface_map_
.find(interface_name
);
285 if (iiter
!= interface_map_
.end()) {
286 Interface
* interface
= iiter
->second
;
287 interface
->ObjectRemoved(object_path
, interface_name
);
290 object
->properties_map
.erase(piter
);
292 if (object
->properties_map
.empty()) {
293 object_map_
.erase(oiter
);
298 void ObjectManager::NameOwnerChanged(const std::string
& old_owner
,
299 const std::string
& new_owner
) {
300 if (!old_owner
.empty()) {
301 ObjectMap::iterator iter
= object_map_
.begin();
302 while (iter
!= object_map_
.end()) {
303 ObjectMap::iterator tmp
= iter
;
306 // PropertiesMap is mutated by RemoveInterface, and also Object is
307 // destroyed; easier to collect the object path and interface names
308 // and remove them safely.
309 const dbus::ObjectPath object_path
= tmp
->first
;
310 Object
* object
= tmp
->second
;
311 std::vector
<std::string
> interfaces
;
313 for (Object::PropertiesMap::iterator piter
=
314 object
->properties_map
.begin();
315 piter
!= object
->properties_map
.end(); ++piter
)
316 interfaces
.push_back(piter
->first
);
318 for (std::vector
<std::string
>::iterator iiter
= interfaces
.begin();
319 iiter
!= interfaces
.end(); ++iiter
)
320 RemoveInterface(object_path
, *iiter
);
325 if (!new_owner
.empty())