Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / chromeos / dbus / peer_daemon_manager_client.cc
blobe30f294a1059a448ffc13e7e9badf1fd10060a6b
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"
7 #include "base/bind.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"
15 #include "dbus/bus.h"
16 #include "dbus/message.h"
17 #include "dbus/object_manager.h"
18 #include "dbus/object_proxy.h"
19 #include "dbus/values_util.h"
21 namespace chromeos {
22 namespace {
24 // TODO(benchan): Move these constants to system_api.
25 namespace peerd {
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";
37 } // namespace peerd
39 // The PeerDaemonManagerClient implementation used in production.
40 class PeerDaemonManagerClientImpl : public PeerDaemonManagerClient,
41 public dbus::ObjectManager::Interface {
42 public:
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;
58 void StartMonitoring(
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;
64 void ExposeService(
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;
83 private:
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) {
116 DCHECK(observer);
117 observers_.AddObserver(observer);
120 void PeerDaemonManagerClientImpl::RemoveObserver(Observer* observer) {
121 DCHECK(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));
153 if (!object_proxy) {
154 base::ThreadTaskRunnerHandle::Get()->PostTask(
155 FROM_HERE,
156 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
157 weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
158 return;
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));
177 if (!object_proxy) {
178 base::ThreadTaskRunnerHandle::Get()->PostTask(
179 FROM_HERE,
180 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod,
181 weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
182 return;
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));
202 if (!object_proxy) {
203 base::ThreadTaskRunnerHandle::Get()->PostTask(
204 FROM_HERE,
205 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
206 weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
207 return;
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));
240 if (!object_proxy) {
241 base::ThreadTaskRunnerHandle::Get()->PostTask(
242 FROM_HERE,
243 base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod,
244 weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
245 return;
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,
258 peerd::kPingMethod);
259 dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
260 dbus::ObjectPath(peerd::kPeerdManagerPath));
261 if (!object_proxy) {
262 base::ThreadTaskRunnerHandle::Get()->PostTask(
263 FROM_HERE,
264 base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
265 weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
266 return;
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(
282 object_proxy,
283 base::Bind(&PeerDaemonManagerClientImpl::OnManagerPropertyChanged,
284 weak_ptr_factory_.GetWeakPtr()));
285 } else if (interface_name == peerd::kServiceInterface) {
286 properties = new ServiceProperties(
287 object_proxy,
288 base::Bind(&PeerDaemonManagerClientImpl::OnServicePropertyChanged,
289 weak_ptr_factory_.GetWeakPtr(), object_path));
290 } else if (interface_name == peerd::kPeerInterface) {
291 properties = new PeerProperties(
292 object_proxy,
293 base::Bind(&PeerDaemonManagerClientImpl::OnPeerPropertyChanged,
294 weak_ptr_factory_.GetWeakPtr(), object_path));
295 } else {
296 NOTREACHED() << "Unhandled interface name " << interface_name;
298 return properties;
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));
310 } else {
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));
324 } else {
325 NOTREACHED() << "Unhandled interface name " << interface_name;
329 void PeerDaemonManagerClientImpl::OnStringDBusMethod(
330 const StringDBusMethodCallback& callback,
331 dbus::Response* response) {
332 if (!response) {
333 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string());
334 return;
337 dbus::MessageReader reader(response);
338 std::string result;
339 if (!reader.PopString(&result)) {
340 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string());
341 return;
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));
382 } // namespace
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() {
423 // static
424 PeerDaemonManagerClient* PeerDaemonManagerClient::Create() {
425 return new PeerDaemonManagerClientImpl();
428 } // namespace chromeos