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
3 // found in the LICENSE file.
5 #include "chromeos/dbus/peer_daemon_manager_client.h"
8 #include "base/callback.h"
9 #include "base/logging.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/observer_list.h"
14 #include "dbus/message.h"
15 #include "dbus/object_manager.h"
16 #include "dbus/object_proxy.h"
17 #include "dbus/values_util.h"
22 // TODO(benchan): Move these constants to system_api.
24 const char kPeerdServiceName
[] = "org.chromium.peerd";
25 const char kPeerdObjectManagerServicePath
[] = "/org/chromium/peerd";
26 const char kPeerdManagerPath
[] = "/org/chromium/peerd/Manager";
27 const char kManagerInterface
[] = "org.chromium.peerd.Manager";
28 const char kServiceInterface
[] = "org.chromium.peerd.Service";
29 const char kPeerInterface
[] = "org.chromium.peerd.Peer";
30 const char kStartMonitoringMethod
[] = "StartMonitoring";
31 const char kStopMonitoringMethod
[] = "StopMonitoring";
32 const char kExposeServiceMethod
[] = "ExposeService";
33 const char kRemoveExposedServiceMethod
[] = "RemoveExposedService";
34 const char kPingMethod
[] = "Ping";
37 // The PeerDaemonManagerClient implementation used in production.
38 class PeerDaemonManagerClientImpl
: public PeerDaemonManagerClient
,
39 public dbus::ObjectManager::Interface
{
41 PeerDaemonManagerClientImpl();
42 ~PeerDaemonManagerClientImpl() override
;
44 // DBusClient overrides.
45 void Init(dbus::Bus
* bus
) override
;
47 // PeerDaemonManagerClient overrides.
48 void AddObserver(Observer
* observer
) override
;
49 void RemoveObserver(Observer
* observer
) override
;
50 std::vector
<dbus::ObjectPath
> GetServices() override
;
51 std::vector
<dbus::ObjectPath
> GetPeers() override
;
52 ServiceProperties
* GetServiceProperties(
53 const dbus::ObjectPath
& object_path
) override
;
54 PeerProperties
* GetPeerProperties(
55 const dbus::ObjectPath
& object_path
) override
;
57 const std::vector
<std::string
>& requested_technologies
,
58 const base::DictionaryValue
& options
,
59 const StringDBusMethodCallback
& callback
) override
;
60 void StopMonitoring(const std::string
& monitoring_token
,
61 const VoidDBusMethodCallback
& callback
) override
;
63 const std::string
& service_id
,
64 const std::map
<std::string
, std::string
>& service_info
,
65 const base::DictionaryValue
& options
,
66 const StringDBusMethodCallback
& callback
) override
;
67 void RemoveExposedService(const std::string
& service_token
,
68 const VoidDBusMethodCallback
& callback
) override
;
69 void Ping(const StringDBusMethodCallback
& callback
) override
;
71 // dbus::ObjectManager::Interface overrides.
72 dbus::PropertySet
* CreateProperties(
73 dbus::ObjectProxy
* object_proxy
,
74 const dbus::ObjectPath
& object_path
,
75 const std::string
& interface_name
) override
;
76 void ObjectAdded(const dbus::ObjectPath
& object_path
,
77 const std::string
& interface_name
) override
;
78 void ObjectRemoved(const dbus::ObjectPath
& object_path
,
79 const std::string
& interface_name
) override
;
82 void OnStringDBusMethod(const StringDBusMethodCallback
& callback
,
83 dbus::Response
* response
);
84 void OnVoidDBusMethod(const VoidDBusMethodCallback
& callback
,
85 dbus::Response
* response
);
86 void OnManagerPropertyChanged(const std::string
& property_name
);
87 void OnServicePropertyChanged(const dbus::ObjectPath
& object_path
,
88 const std::string
& property_name
);
89 void OnPeerPropertyChanged(const dbus::ObjectPath
& object_path
,
90 const std::string
& property_name
);
92 // List of observers interested in event notifications from us.
93 ObserverList
<Observer
> observers_
;
94 dbus::ObjectManager
* object_manager_
;
96 base::WeakPtrFactory
<PeerDaemonManagerClientImpl
> weak_ptr_factory_
;
98 DISALLOW_COPY_AND_ASSIGN(PeerDaemonManagerClientImpl
);
101 PeerDaemonManagerClientImpl::PeerDaemonManagerClientImpl()
102 : object_manager_(nullptr), weak_ptr_factory_(this) {
105 PeerDaemonManagerClientImpl::~PeerDaemonManagerClientImpl() {
106 if (object_manager_
) {
107 object_manager_
->UnregisterInterface(peerd::kManagerInterface
);
108 object_manager_
->UnregisterInterface(peerd::kServiceInterface
);
109 object_manager_
->UnregisterInterface(peerd::kPeerInterface
);
113 void PeerDaemonManagerClientImpl::AddObserver(Observer
* observer
) {
115 observers_
.AddObserver(observer
);
118 void PeerDaemonManagerClientImpl::RemoveObserver(Observer
* observer
) {
120 observers_
.RemoveObserver(observer
);
123 std::vector
<dbus::ObjectPath
> PeerDaemonManagerClientImpl::GetServices() {
124 return object_manager_
->GetObjectsWithInterface(peerd::kServiceInterface
);
127 std::vector
<dbus::ObjectPath
> PeerDaemonManagerClientImpl::GetPeers() {
128 return object_manager_
->GetObjectsWithInterface(peerd::kPeerInterface
);
131 PeerDaemonManagerClient::ServiceProperties
*
132 PeerDaemonManagerClientImpl::GetServiceProperties(
133 const dbus::ObjectPath
& object_path
) {
134 return static_cast<ServiceProperties
*>(
135 object_manager_
->GetProperties(object_path
, peerd::kServiceInterface
));
138 PeerDaemonManagerClient::PeerProperties
*
139 PeerDaemonManagerClientImpl::GetPeerProperties(
140 const dbus::ObjectPath
& object_path
) {
141 return static_cast<PeerProperties
*>(
142 object_manager_
->GetProperties(object_path
, peerd::kPeerInterface
));
145 void PeerDaemonManagerClientImpl::StartMonitoring(
146 const std::vector
<std::string
>& requested_technologies
,
147 const base::DictionaryValue
& options
,
148 const StringDBusMethodCallback
& callback
) {
149 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
150 dbus::ObjectPath(peerd::kPeerdManagerPath
));
152 base::MessageLoop::current()->PostTask(
154 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
155 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
159 dbus::MethodCall
method_call(peerd::kManagerInterface
,
160 peerd::kStartMonitoringMethod
);
161 dbus::MessageWriter
writer(&method_call
);
162 writer
.AppendArrayOfStrings(requested_technologies
);
163 dbus::AppendValueData(&writer
, options
);
164 object_proxy
->CallMethod(
165 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
166 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
167 weak_ptr_factory_
.GetWeakPtr(), callback
));
170 void PeerDaemonManagerClientImpl::StopMonitoring(
171 const std::string
& monitoring_token
,
172 const VoidDBusMethodCallback
& callback
) {
173 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
174 dbus::ObjectPath(peerd::kPeerdManagerPath
));
176 base::MessageLoop::current()->PostTask(
178 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod
,
179 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
183 dbus::MethodCall
method_call(peerd::kManagerInterface
,
184 peerd::kStopMonitoringMethod
);
185 dbus::MessageWriter
writer(&method_call
);
186 writer
.AppendString(monitoring_token
);
187 object_proxy
->CallMethod(
188 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
189 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod
,
190 weak_ptr_factory_
.GetWeakPtr(), callback
));
193 void PeerDaemonManagerClientImpl::ExposeService(
194 const std::string
& service_id
,
195 const std::map
<std::string
, std::string
>& service_info
,
196 const base::DictionaryValue
& options
,
197 const StringDBusMethodCallback
& callback
) {
198 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
199 dbus::ObjectPath(peerd::kPeerdManagerPath
));
201 base::MessageLoop::current()->PostTask(
203 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
204 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
208 dbus::MethodCall
method_call(peerd::kManagerInterface
,
209 peerd::kExposeServiceMethod
);
210 dbus::MessageWriter
writer(&method_call
);
211 writer
.AppendString(service_id
);
213 dbus::MessageWriter
array_writer(nullptr);
214 writer
.OpenArray("{ss}", &array_writer
);
215 for (const auto& entry
: service_info
) {
216 dbus::MessageWriter
dict_entry_writer(nullptr);
217 array_writer
.OpenDictEntry(&dict_entry_writer
);
218 dict_entry_writer
.AppendString(entry
.first
);
219 dict_entry_writer
.AppendString(entry
.second
);
220 array_writer
.CloseContainer(&dict_entry_writer
);
222 writer
.CloseContainer(&array_writer
);
224 dbus::AppendValueData(&writer
, options
);
225 object_proxy
->CallMethod(
226 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
227 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
228 weak_ptr_factory_
.GetWeakPtr(), callback
));
231 void PeerDaemonManagerClientImpl::RemoveExposedService(
232 const std::string
& service_token
,
233 const VoidDBusMethodCallback
& callback
) {
234 dbus::MethodCall
method_call(peerd::kManagerInterface
,
235 peerd::kRemoveExposedServiceMethod
);
236 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
237 dbus::ObjectPath(peerd::kPeerdManagerPath
));
239 base::MessageLoop::current()->PostTask(
241 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod
,
242 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
245 dbus::MessageWriter
writer(&method_call
);
246 writer
.AppendString(service_token
);
247 object_proxy
->CallMethod(
248 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
249 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod
,
250 weak_ptr_factory_
.GetWeakPtr(), callback
));
253 void PeerDaemonManagerClientImpl::Ping(
254 const StringDBusMethodCallback
& callback
) {
255 dbus::MethodCall
method_call(peerd::kManagerInterface
,
257 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
258 dbus::ObjectPath(peerd::kPeerdManagerPath
));
260 base::MessageLoop::current()->PostTask(
262 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
263 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
266 dbus::MessageWriter
writer(&method_call
);
267 object_proxy
->CallMethod(
268 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
269 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
270 weak_ptr_factory_
.GetWeakPtr(), callback
));
273 dbus::PropertySet
* PeerDaemonManagerClientImpl::CreateProperties(
274 dbus::ObjectProxy
* object_proxy
,
275 const dbus::ObjectPath
& object_path
,
276 const std::string
& interface_name
) {
277 dbus::PropertySet
* properties
= nullptr;
278 if (interface_name
== peerd::kManagerInterface
) {
279 properties
= new ManagerProperties(
281 base::Bind(&PeerDaemonManagerClientImpl::OnManagerPropertyChanged
,
282 weak_ptr_factory_
.GetWeakPtr()));
283 } else if (interface_name
== peerd::kServiceInterface
) {
284 properties
= new ServiceProperties(
286 base::Bind(&PeerDaemonManagerClientImpl::OnServicePropertyChanged
,
287 weak_ptr_factory_
.GetWeakPtr(), object_path
));
288 } else if (interface_name
== peerd::kPeerInterface
) {
289 properties
= new PeerProperties(
291 base::Bind(&PeerDaemonManagerClientImpl::OnPeerPropertyChanged
,
292 weak_ptr_factory_
.GetWeakPtr(), object_path
));
294 NOTREACHED() << "Unhandled interface name " << interface_name
;
299 void PeerDaemonManagerClientImpl::ObjectAdded(
300 const dbus::ObjectPath
& object_path
,
301 const std::string
& interface_name
) {
302 if (interface_name
== peerd::kManagerInterface
) {
303 FOR_EACH_OBSERVER(Observer
, observers_
, ManagerAdded());
304 } else if (interface_name
== peerd::kServiceInterface
) {
305 FOR_EACH_OBSERVER(Observer
, observers_
, ServiceAdded(object_path
));
306 } else if (interface_name
== peerd::kPeerInterface
) {
307 FOR_EACH_OBSERVER(Observer
, observers_
, PeerAdded(object_path
));
309 NOTREACHED() << "Unhandled interface name " << interface_name
;
313 void PeerDaemonManagerClientImpl::ObjectRemoved(
314 const dbus::ObjectPath
& object_path
,
315 const std::string
& interface_name
) {
316 if (interface_name
== peerd::kManagerInterface
) {
317 FOR_EACH_OBSERVER(Observer
, observers_
, ManagerRemoved());
318 } else if (interface_name
== peerd::kServiceInterface
) {
319 FOR_EACH_OBSERVER(Observer
, observers_
, ServiceRemoved(object_path
));
320 } else if (interface_name
== peerd::kPeerInterface
) {
321 FOR_EACH_OBSERVER(Observer
, observers_
, PeerRemoved(object_path
));
323 NOTREACHED() << "Unhandled interface name " << interface_name
;
327 void PeerDaemonManagerClientImpl::OnStringDBusMethod(
328 const StringDBusMethodCallback
& callback
,
329 dbus::Response
* response
) {
331 callback
.Run(DBUS_METHOD_CALL_FAILURE
, std::string());
335 dbus::MessageReader
reader(response
);
337 if (!reader
.PopString(&result
)) {
338 callback
.Run(DBUS_METHOD_CALL_FAILURE
, std::string());
342 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, result
);
345 void PeerDaemonManagerClientImpl::OnVoidDBusMethod(
346 const VoidDBusMethodCallback
& callback
,
347 dbus::Response
* response
) {
348 callback
.Run(response
? DBUS_METHOD_CALL_SUCCESS
: DBUS_METHOD_CALL_FAILURE
);
351 void PeerDaemonManagerClientImpl::Init(dbus::Bus
* bus
) {
352 object_manager_
= bus
->GetObjectManager(
353 peerd::kPeerdServiceName
,
354 dbus::ObjectPath(peerd::kPeerdObjectManagerServicePath
));
355 object_manager_
->RegisterInterface(peerd::kManagerInterface
, this);
356 object_manager_
->RegisterInterface(peerd::kServiceInterface
, this);
357 object_manager_
->RegisterInterface(peerd::kPeerInterface
, this);
360 void PeerDaemonManagerClientImpl::OnManagerPropertyChanged(
361 const std::string
& property_name
) {
362 FOR_EACH_OBSERVER(Observer
, observers_
,
363 ManagerPropertyChanged(property_name
));
366 void PeerDaemonManagerClientImpl::OnServicePropertyChanged(
367 const dbus::ObjectPath
& object_path
,
368 const std::string
& property_name
) {
369 FOR_EACH_OBSERVER(Observer
, observers_
,
370 ServicePropertyChanged(object_path
, property_name
));
373 void PeerDaemonManagerClientImpl::OnPeerPropertyChanged(
374 const dbus::ObjectPath
& object_path
,
375 const std::string
& property_name
) {
376 FOR_EACH_OBSERVER(Observer
, observers_
,
377 PeerPropertyChanged(object_path
, property_name
));
382 PeerDaemonManagerClient::ManagerProperties::ManagerProperties(
383 dbus::ObjectProxy
* object_proxy
,
384 const PropertyChangedCallback
& callback
)
385 : dbus::PropertySet
{object_proxy
, peerd::kManagerInterface
, callback
} {
386 RegisterProperty("MonitoredTechnologies", &monitored_technologies_
);
389 PeerDaemonManagerClient::ManagerProperties::~ManagerProperties() {
392 PeerDaemonManagerClient::ServiceProperties::ServiceProperties(
393 dbus::ObjectProxy
* object_proxy
,
394 const PropertyChangedCallback
& callback
)
395 : dbus::PropertySet
{object_proxy
, peerd::kServiceInterface
, callback
} {
396 RegisterProperty("ServiceId", &service_id_
);
397 RegisterProperty("ServiceInfo", &service_info_
);
398 RegisterProperty("IpInfos", &ip_infos_
);
401 PeerDaemonManagerClient::ServiceProperties::~ServiceProperties() {
404 PeerDaemonManagerClient::PeerProperties::PeerProperties(
405 dbus::ObjectProxy
* object_proxy
,
406 const PropertyChangedCallback
& callback
)
407 : dbus::PropertySet
{object_proxy
, peerd::kPeerInterface
, callback
} {
408 RegisterProperty("UUID", &uuid_
);
409 RegisterProperty("LastSeen", &last_seen_
);
412 PeerDaemonManagerClient::PeerProperties::~PeerProperties() {
415 PeerDaemonManagerClient::PeerDaemonManagerClient() {
418 PeerDaemonManagerClient::~PeerDaemonManagerClient() {
422 PeerDaemonManagerClient
* PeerDaemonManagerClient::Create() {
423 return new PeerDaemonManagerClientImpl();
426 } // namespace chromeos