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_
);
36 object_proxy_
->ConnectToSignal(
37 kObjectManagerInterface
,
38 kObjectManagerInterfacesAdded
,
39 base::Bind(&ObjectManager::InterfacesAddedReceived
,
40 weak_ptr_factory_
.GetWeakPtr()),
41 base::Bind(&ObjectManager::InterfacesAddedConnected
,
42 weak_ptr_factory_
.GetWeakPtr()));
44 object_proxy_
->ConnectToSignal(
45 kObjectManagerInterface
,
46 kObjectManagerInterfacesRemoved
,
47 base::Bind(&ObjectManager::InterfacesRemovedReceived
,
48 weak_ptr_factory_
.GetWeakPtr()),
49 base::Bind(&ObjectManager::InterfacesRemovedConnected
,
50 weak_ptr_factory_
.GetWeakPtr()));
55 ObjectManager::~ObjectManager() {
56 // Clean up Object structures
57 for (ObjectMap::iterator iter
= object_map_
.begin();
58 iter
!= object_map_
.end(); ++iter
) {
59 Object
* object
= iter
->second
;
61 for (Object::PropertiesMap::iterator piter
= object
->properties_map
.begin();
62 piter
!= object
->properties_map
.end(); ++piter
) {
63 PropertySet
* properties
= piter
->second
;
71 void ObjectManager::RegisterInterface(const std::string
& interface_name
,
72 Interface
* interface
) {
73 interface_map_
[interface_name
] = interface
;
76 void ObjectManager::UnregisterInterface(const std::string
& interface_name
) {
77 InterfaceMap::iterator iter
= interface_map_
.find(interface_name
);
78 if (iter
!= interface_map_
.end())
79 interface_map_
.erase(iter
);
82 std::vector
<ObjectPath
> ObjectManager::GetObjects() {
83 std::vector
<ObjectPath
> object_paths
;
85 for (ObjectMap::iterator iter
= object_map_
.begin();
86 iter
!= object_map_
.end(); ++iter
)
87 object_paths
.push_back(iter
->first
);
92 std::vector
<ObjectPath
> ObjectManager::GetObjectsWithInterface(
93 const std::string
& interface_name
) {
94 std::vector
<ObjectPath
> object_paths
;
96 for (ObjectMap::iterator oiter
= object_map_
.begin();
97 oiter
!= object_map_
.end(); ++oiter
) {
98 Object
* object
= oiter
->second
;
100 Object::PropertiesMap::iterator piter
=
101 object
->properties_map
.find(interface_name
);
102 if (piter
!= object
->properties_map
.end())
103 object_paths
.push_back(oiter
->first
);
109 ObjectProxy
* ObjectManager::GetObjectProxy(const ObjectPath
& object_path
) {
110 ObjectMap::iterator iter
= object_map_
.find(object_path
);
111 if (iter
== object_map_
.end())
114 Object
* object
= iter
->second
;
115 return object
->object_proxy
;
118 PropertySet
* ObjectManager::GetProperties(const ObjectPath
& object_path
,
119 const std::string
& interface_name
) {
120 ObjectMap::iterator iter
= object_map_
.find(object_path
);
121 if (iter
== object_map_
.end())
124 Object
* object
= iter
->second
;
125 Object::PropertiesMap::iterator piter
=
126 object
->properties_map
.find(interface_name
);
127 if (piter
== object
->properties_map
.end())
130 return piter
->second
;
133 void ObjectManager::GetManagedObjects() {
134 MethodCall
method_call(kObjectManagerInterface
,
135 kObjectManagerGetManagedObjects
);
137 object_proxy_
->CallMethod(
139 ObjectProxy::TIMEOUT_USE_DEFAULT
,
140 base::Bind(&ObjectManager::OnGetManagedObjects
,
141 weak_ptr_factory_
.GetWeakPtr()));
144 void ObjectManager::OnGetManagedObjects(Response
* response
) {
145 if (response
!= NULL
) {
146 MessageReader
reader(response
);
147 MessageReader
array_reader(NULL
);
148 if (!reader
.PopArray(&array_reader
))
151 while (array_reader
.HasMoreData()) {
152 MessageReader
dict_entry_reader(NULL
);
153 ObjectPath object_path
;
154 if (!array_reader
.PopDictEntry(&dict_entry_reader
) ||
155 !dict_entry_reader
.PopObjectPath(&object_path
))
158 UpdateObject(object_path
, &dict_entry_reader
);
162 LOG(WARNING
) << service_name_
<< " " << object_path_
.value()
163 << ": Failed to get managed objects";
167 void ObjectManager::InterfacesAddedReceived(Signal
* signal
) {
169 MessageReader
reader(signal
);
170 ObjectPath object_path
;
171 if (!reader
.PopObjectPath(&object_path
)) {
172 LOG(WARNING
) << service_name_
<< " " << object_path_
.value()
173 << ": InterfacesAdded signal has incorrect parameters: "
174 << signal
->ToString();
178 UpdateObject(object_path
, &reader
);
181 void ObjectManager::InterfacesAddedConnected(const std::string
& interface_name
,
182 const std::string
& signal_name
,
184 LOG_IF(WARNING
, !success
) << service_name_
<< " " << object_path_
.value()
185 << ": Failed to connect to InterfacesAdded signal.";
188 void ObjectManager::InterfacesRemovedReceived(Signal
* signal
) {
190 MessageReader
reader(signal
);
191 ObjectPath object_path
;
192 std::vector
<std::string
> interface_names
;
193 if (!reader
.PopObjectPath(&object_path
) ||
194 !reader
.PopArrayOfStrings(&interface_names
)) {
195 LOG(WARNING
) << service_name_
<< " " << object_path_
.value()
196 << ": InterfacesRemoved signal has incorrect parameters: "
197 << signal
->ToString();
201 for (size_t i
= 0; i
< interface_names
.size(); ++i
)
202 RemoveInterface(object_path
, interface_names
[i
]);
205 void ObjectManager::InterfacesRemovedConnected(
206 const std::string
& interface_name
,
207 const std::string
& signal_name
,
209 LOG_IF(WARNING
, !success
) << service_name_
<< " " << object_path_
.value()
210 << ": Failed to connect to "
211 << "InterfacesRemoved signal.";
214 void ObjectManager::UpdateObject(const ObjectPath
& object_path
,
215 MessageReader
* reader
) {
217 MessageReader
array_reader(NULL
);
218 if (!reader
->PopArray(&array_reader
))
221 while (array_reader
.HasMoreData()) {
222 MessageReader
dict_entry_reader(NULL
);
223 std::string interface_name
;
224 if (!array_reader
.PopDictEntry(&dict_entry_reader
) ||
225 !dict_entry_reader
.PopString(&interface_name
))
228 AddInterface(object_path
, interface_name
, &dict_entry_reader
);
233 void ObjectManager::AddInterface(const ObjectPath
& object_path
,
234 const std::string
& interface_name
,
235 MessageReader
* reader
) {
236 InterfaceMap::iterator iiter
= interface_map_
.find(interface_name
);
237 if (iiter
== interface_map_
.end())
239 Interface
* interface
= iiter
->second
;
241 ObjectMap::iterator oiter
= object_map_
.find(object_path
);
243 if (oiter
== object_map_
.end()) {
244 object
= object_map_
[object_path
] = new Object
;
245 object
->object_proxy
= bus_
->GetObjectProxy(service_name_
, object_path
);
247 object
= oiter
->second
;
249 Object::PropertiesMap::iterator piter
=
250 object
->properties_map
.find(interface_name
);
251 PropertySet
* property_set
;
252 const bool interface_added
= (piter
== object
->properties_map
.end());
253 if (interface_added
) {
254 property_set
= object
->properties_map
[interface_name
] =
255 interface
->CreateProperties(object
->object_proxy
,
256 object_path
, interface_name
);
257 property_set
->ConnectSignals();
259 property_set
= piter
->second
;
261 property_set
->UpdatePropertiesFromReader(reader
);
264 interface
->ObjectAdded(object_path
, interface_name
);
267 void ObjectManager::RemoveInterface(const ObjectPath
& object_path
,
268 const std::string
& interface_name
) {
269 ObjectMap::iterator oiter
= object_map_
.find(object_path
);
270 if (oiter
== object_map_
.end())
272 Object
* object
= oiter
->second
;
274 Object::PropertiesMap::iterator piter
=
275 object
->properties_map
.find(interface_name
);
276 if (piter
== object
->properties_map
.end())
279 // Inform the interface before removing the properties structure or object
280 // in case it needs details from them to make its own decisions.
281 InterfaceMap::iterator iiter
= interface_map_
.find(interface_name
);
282 if (iiter
!= interface_map_
.end()) {
283 Interface
* interface
= iiter
->second
;
284 interface
->ObjectRemoved(object_path
, interface_name
);
287 object
->properties_map
.erase(piter
);
289 if (object
->properties_map
.empty()) {
290 object_map_
.erase(oiter
);