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/location.h"
10 #include "base/logging.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/observer_list.h"
13 #include "base/single_thread_task_runner.h"
14 #include "base/thread_task_runner_handle.h"
16 #include "dbus/message.h"
17 #include "dbus/object_manager.h"
18 #include "dbus/object_proxy.h"
19 #include "dbus/values_util.h"
24 // TODO(benchan): Move these constants to system_api.
26 const char kPeerdServiceName
[] = "org.chromium.peerd";
27 const char kPeerdObjectManagerServicePath
[] = "/org/chromium/peerd";
28 const char kPeerdManagerPath
[] = "/org/chromium/peerd/Manager";
29 const char kManagerInterface
[] = "org.chromium.peerd.Manager";
30 const char kServiceInterface
[] = "org.chromium.peerd.Service";
31 const char kPeerInterface
[] = "org.chromium.peerd.Peer";
32 const char kStartMonitoringMethod
[] = "StartMonitoring";
33 const char kStopMonitoringMethod
[] = "StopMonitoring";
34 const char kExposeServiceMethod
[] = "ExposeService";
35 const char kRemoveExposedServiceMethod
[] = "RemoveExposedService";
36 const char kPingMethod
[] = "Ping";
39 // The PeerDaemonManagerClient implementation used in production.
40 class PeerDaemonManagerClientImpl
: public PeerDaemonManagerClient
,
41 public dbus::ObjectManager::Interface
{
43 PeerDaemonManagerClientImpl();
44 ~PeerDaemonManagerClientImpl() override
;
46 // DBusClient overrides.
47 void Init(dbus::Bus
* bus
) override
;
49 // PeerDaemonManagerClient overrides.
50 void AddObserver(Observer
* observer
) override
;
51 void RemoveObserver(Observer
* observer
) override
;
52 std::vector
<dbus::ObjectPath
> GetServices() override
;
53 std::vector
<dbus::ObjectPath
> GetPeers() override
;
54 ServiceProperties
* GetServiceProperties(
55 const dbus::ObjectPath
& object_path
) override
;
56 PeerProperties
* GetPeerProperties(
57 const dbus::ObjectPath
& object_path
) override
;
59 const std::vector
<std::string
>& requested_technologies
,
60 const base::DictionaryValue
& options
,
61 const StringDBusMethodCallback
& callback
) override
;
62 void StopMonitoring(const std::string
& monitoring_token
,
63 const VoidDBusMethodCallback
& callback
) override
;
65 const std::string
& service_id
,
66 const std::map
<std::string
, std::string
>& service_info
,
67 const base::DictionaryValue
& options
,
68 const StringDBusMethodCallback
& callback
) override
;
69 void RemoveExposedService(const std::string
& service_token
,
70 const VoidDBusMethodCallback
& callback
) override
;
71 void Ping(const StringDBusMethodCallback
& callback
) override
;
73 // dbus::ObjectManager::Interface overrides.
74 dbus::PropertySet
* CreateProperties(
75 dbus::ObjectProxy
* object_proxy
,
76 const dbus::ObjectPath
& object_path
,
77 const std::string
& interface_name
) override
;
78 void ObjectAdded(const dbus::ObjectPath
& object_path
,
79 const std::string
& interface_name
) override
;
80 void ObjectRemoved(const dbus::ObjectPath
& object_path
,
81 const std::string
& interface_name
) override
;
84 void OnStringDBusMethod(const StringDBusMethodCallback
& callback
,
85 dbus::Response
* response
);
86 void OnVoidDBusMethod(const VoidDBusMethodCallback
& callback
,
87 dbus::Response
* response
);
88 void OnManagerPropertyChanged(const std::string
& property_name
);
89 void OnServicePropertyChanged(const dbus::ObjectPath
& object_path
,
90 const std::string
& property_name
);
91 void OnPeerPropertyChanged(const dbus::ObjectPath
& object_path
,
92 const std::string
& property_name
);
94 // List of observers interested in event notifications from us.
95 base::ObserverList
<Observer
> observers_
;
96 dbus::ObjectManager
* object_manager_
;
98 base::WeakPtrFactory
<PeerDaemonManagerClientImpl
> weak_ptr_factory_
;
100 DISALLOW_COPY_AND_ASSIGN(PeerDaemonManagerClientImpl
);
103 PeerDaemonManagerClientImpl::PeerDaemonManagerClientImpl()
104 : object_manager_(nullptr), weak_ptr_factory_(this) {
107 PeerDaemonManagerClientImpl::~PeerDaemonManagerClientImpl() {
108 if (object_manager_
) {
109 object_manager_
->UnregisterInterface(peerd::kManagerInterface
);
110 object_manager_
->UnregisterInterface(peerd::kServiceInterface
);
111 object_manager_
->UnregisterInterface(peerd::kPeerInterface
);
115 void PeerDaemonManagerClientImpl::AddObserver(Observer
* observer
) {
117 observers_
.AddObserver(observer
);
120 void PeerDaemonManagerClientImpl::RemoveObserver(Observer
* observer
) {
122 observers_
.RemoveObserver(observer
);
125 std::vector
<dbus::ObjectPath
> PeerDaemonManagerClientImpl::GetServices() {
126 return object_manager_
->GetObjectsWithInterface(peerd::kServiceInterface
);
129 std::vector
<dbus::ObjectPath
> PeerDaemonManagerClientImpl::GetPeers() {
130 return object_manager_
->GetObjectsWithInterface(peerd::kPeerInterface
);
133 PeerDaemonManagerClient::ServiceProperties
*
134 PeerDaemonManagerClientImpl::GetServiceProperties(
135 const dbus::ObjectPath
& object_path
) {
136 return static_cast<ServiceProperties
*>(
137 object_manager_
->GetProperties(object_path
, peerd::kServiceInterface
));
140 PeerDaemonManagerClient::PeerProperties
*
141 PeerDaemonManagerClientImpl::GetPeerProperties(
142 const dbus::ObjectPath
& object_path
) {
143 return static_cast<PeerProperties
*>(
144 object_manager_
->GetProperties(object_path
, peerd::kPeerInterface
));
147 void PeerDaemonManagerClientImpl::StartMonitoring(
148 const std::vector
<std::string
>& requested_technologies
,
149 const base::DictionaryValue
& options
,
150 const StringDBusMethodCallback
& callback
) {
151 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
152 dbus::ObjectPath(peerd::kPeerdManagerPath
));
154 base::ThreadTaskRunnerHandle::Get()->PostTask(
156 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
157 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
161 dbus::MethodCall
method_call(peerd::kManagerInterface
,
162 peerd::kStartMonitoringMethod
);
163 dbus::MessageWriter
writer(&method_call
);
164 writer
.AppendArrayOfStrings(requested_technologies
);
165 dbus::AppendValueData(&writer
, options
);
166 object_proxy
->CallMethod(
167 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
168 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
169 weak_ptr_factory_
.GetWeakPtr(), callback
));
172 void PeerDaemonManagerClientImpl::StopMonitoring(
173 const std::string
& monitoring_token
,
174 const VoidDBusMethodCallback
& callback
) {
175 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
176 dbus::ObjectPath(peerd::kPeerdManagerPath
));
178 base::ThreadTaskRunnerHandle::Get()->PostTask(
180 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod
,
181 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
185 dbus::MethodCall
method_call(peerd::kManagerInterface
,
186 peerd::kStopMonitoringMethod
);
187 dbus::MessageWriter
writer(&method_call
);
188 writer
.AppendString(monitoring_token
);
189 object_proxy
->CallMethod(
190 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
191 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod
,
192 weak_ptr_factory_
.GetWeakPtr(), callback
));
195 void PeerDaemonManagerClientImpl::ExposeService(
196 const std::string
& service_id
,
197 const std::map
<std::string
, std::string
>& service_info
,
198 const base::DictionaryValue
& options
,
199 const StringDBusMethodCallback
& callback
) {
200 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
201 dbus::ObjectPath(peerd::kPeerdManagerPath
));
203 base::ThreadTaskRunnerHandle::Get()->PostTask(
205 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
206 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
210 dbus::MethodCall
method_call(peerd::kManagerInterface
,
211 peerd::kExposeServiceMethod
);
212 dbus::MessageWriter
writer(&method_call
);
213 writer
.AppendString(service_id
);
215 dbus::MessageWriter
array_writer(nullptr);
216 writer
.OpenArray("{ss}", &array_writer
);
217 for (const auto& entry
: service_info
) {
218 dbus::MessageWriter
dict_entry_writer(nullptr);
219 array_writer
.OpenDictEntry(&dict_entry_writer
);
220 dict_entry_writer
.AppendString(entry
.first
);
221 dict_entry_writer
.AppendString(entry
.second
);
222 array_writer
.CloseContainer(&dict_entry_writer
);
224 writer
.CloseContainer(&array_writer
);
226 dbus::AppendValueData(&writer
, options
);
227 object_proxy
->CallMethod(
228 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
229 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
230 weak_ptr_factory_
.GetWeakPtr(), callback
));
233 void PeerDaemonManagerClientImpl::RemoveExposedService(
234 const std::string
& service_token
,
235 const VoidDBusMethodCallback
& callback
) {
236 dbus::MethodCall
method_call(peerd::kManagerInterface
,
237 peerd::kRemoveExposedServiceMethod
);
238 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
239 dbus::ObjectPath(peerd::kPeerdManagerPath
));
241 base::ThreadTaskRunnerHandle::Get()->PostTask(
243 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod
,
244 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
247 dbus::MessageWriter
writer(&method_call
);
248 writer
.AppendString(service_token
);
249 object_proxy
->CallMethod(
250 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
251 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod
,
252 weak_ptr_factory_
.GetWeakPtr(), callback
));
255 void PeerDaemonManagerClientImpl::Ping(
256 const StringDBusMethodCallback
& callback
) {
257 dbus::MethodCall
method_call(peerd::kManagerInterface
,
259 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
260 dbus::ObjectPath(peerd::kPeerdManagerPath
));
262 base::ThreadTaskRunnerHandle::Get()->PostTask(
264 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
265 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
268 dbus::MessageWriter
writer(&method_call
);
269 object_proxy
->CallMethod(
270 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
271 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod
,
272 weak_ptr_factory_
.GetWeakPtr(), callback
));
275 dbus::PropertySet
* PeerDaemonManagerClientImpl::CreateProperties(
276 dbus::ObjectProxy
* object_proxy
,
277 const dbus::ObjectPath
& object_path
,
278 const std::string
& interface_name
) {
279 dbus::PropertySet
* properties
= nullptr;
280 if (interface_name
== peerd::kManagerInterface
) {
281 properties
= new ManagerProperties(
283 base::Bind(&PeerDaemonManagerClientImpl::OnManagerPropertyChanged
,
284 weak_ptr_factory_
.GetWeakPtr()));
285 } else if (interface_name
== peerd::kServiceInterface
) {
286 properties
= new ServiceProperties(
288 base::Bind(&PeerDaemonManagerClientImpl::OnServicePropertyChanged
,
289 weak_ptr_factory_
.GetWeakPtr(), object_path
));
290 } else if (interface_name
== peerd::kPeerInterface
) {
291 properties
= new PeerProperties(
293 base::Bind(&PeerDaemonManagerClientImpl::OnPeerPropertyChanged
,
294 weak_ptr_factory_
.GetWeakPtr(), object_path
));
296 NOTREACHED() << "Unhandled interface name " << interface_name
;
301 void PeerDaemonManagerClientImpl::ObjectAdded(
302 const dbus::ObjectPath
& object_path
,
303 const std::string
& interface_name
) {
304 if (interface_name
== peerd::kManagerInterface
) {
305 FOR_EACH_OBSERVER(Observer
, observers_
, ManagerAdded());
306 } else if (interface_name
== peerd::kServiceInterface
) {
307 FOR_EACH_OBSERVER(Observer
, observers_
, ServiceAdded(object_path
));
308 } else if (interface_name
== peerd::kPeerInterface
) {
309 FOR_EACH_OBSERVER(Observer
, observers_
, PeerAdded(object_path
));
311 NOTREACHED() << "Unhandled interface name " << interface_name
;
315 void PeerDaemonManagerClientImpl::ObjectRemoved(
316 const dbus::ObjectPath
& object_path
,
317 const std::string
& interface_name
) {
318 if (interface_name
== peerd::kManagerInterface
) {
319 FOR_EACH_OBSERVER(Observer
, observers_
, ManagerRemoved());
320 } else if (interface_name
== peerd::kServiceInterface
) {
321 FOR_EACH_OBSERVER(Observer
, observers_
, ServiceRemoved(object_path
));
322 } else if (interface_name
== peerd::kPeerInterface
) {
323 FOR_EACH_OBSERVER(Observer
, observers_
, PeerRemoved(object_path
));
325 NOTREACHED() << "Unhandled interface name " << interface_name
;
329 void PeerDaemonManagerClientImpl::OnStringDBusMethod(
330 const StringDBusMethodCallback
& callback
,
331 dbus::Response
* response
) {
333 callback
.Run(DBUS_METHOD_CALL_FAILURE
, std::string());
337 dbus::MessageReader
reader(response
);
339 if (!reader
.PopString(&result
)) {
340 callback
.Run(DBUS_METHOD_CALL_FAILURE
, std::string());
344 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, result
);
347 void PeerDaemonManagerClientImpl::OnVoidDBusMethod(
348 const VoidDBusMethodCallback
& callback
,
349 dbus::Response
* response
) {
350 callback
.Run(response
? DBUS_METHOD_CALL_SUCCESS
: DBUS_METHOD_CALL_FAILURE
);
353 void PeerDaemonManagerClientImpl::Init(dbus::Bus
* bus
) {
354 object_manager_
= bus
->GetObjectManager(
355 peerd::kPeerdServiceName
,
356 dbus::ObjectPath(peerd::kPeerdObjectManagerServicePath
));
357 object_manager_
->RegisterInterface(peerd::kManagerInterface
, this);
358 object_manager_
->RegisterInterface(peerd::kServiceInterface
, this);
359 object_manager_
->RegisterInterface(peerd::kPeerInterface
, this);
362 void PeerDaemonManagerClientImpl::OnManagerPropertyChanged(
363 const std::string
& property_name
) {
364 FOR_EACH_OBSERVER(Observer
, observers_
,
365 ManagerPropertyChanged(property_name
));
368 void PeerDaemonManagerClientImpl::OnServicePropertyChanged(
369 const dbus::ObjectPath
& object_path
,
370 const std::string
& property_name
) {
371 FOR_EACH_OBSERVER(Observer
, observers_
,
372 ServicePropertyChanged(object_path
, property_name
));
375 void PeerDaemonManagerClientImpl::OnPeerPropertyChanged(
376 const dbus::ObjectPath
& object_path
,
377 const std::string
& property_name
) {
378 FOR_EACH_OBSERVER(Observer
, observers_
,
379 PeerPropertyChanged(object_path
, property_name
));
384 PeerDaemonManagerClient::ManagerProperties::ManagerProperties(
385 dbus::ObjectProxy
* object_proxy
,
386 const PropertyChangedCallback
& callback
)
387 : dbus::PropertySet
{object_proxy
, peerd::kManagerInterface
, callback
} {
388 RegisterProperty("MonitoredTechnologies", &monitored_technologies_
);
391 PeerDaemonManagerClient::ManagerProperties::~ManagerProperties() {
394 PeerDaemonManagerClient::ServiceProperties::ServiceProperties(
395 dbus::ObjectProxy
* object_proxy
,
396 const PropertyChangedCallback
& callback
)
397 : dbus::PropertySet
{object_proxy
, peerd::kServiceInterface
, callback
} {
398 RegisterProperty("ServiceId", &service_id_
);
399 RegisterProperty("ServiceInfo", &service_info_
);
400 RegisterProperty("IpInfos", &ip_infos_
);
403 PeerDaemonManagerClient::ServiceProperties::~ServiceProperties() {
406 PeerDaemonManagerClient::PeerProperties::PeerProperties(
407 dbus::ObjectProxy
* object_proxy
,
408 const PropertyChangedCallback
& callback
)
409 : dbus::PropertySet
{object_proxy
, peerd::kPeerInterface
, callback
} {
410 RegisterProperty("UUID", &uuid_
);
411 RegisterProperty("LastSeen", &last_seen_
);
414 PeerDaemonManagerClient::PeerProperties::~PeerProperties() {
417 PeerDaemonManagerClient::PeerDaemonManagerClient() {
420 PeerDaemonManagerClient::~PeerDaemonManagerClient() {
424 PeerDaemonManagerClient
* PeerDaemonManagerClient::Create() {
425 return new PeerDaemonManagerClientImpl();
428 } // namespace chromeos