1 // Copyright 2015 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/leadership_daemon_manager_client.h"
8 #include "base/logging.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/observer_list.h"
13 #include "dbus/message.h"
14 #include "dbus/object_manager.h"
15 #include "dbus/object_proxy.h"
16 #include "dbus/values_util.h"
20 // TODO(benchan): Move these constants to system_api.
22 const char kLeaderdServiceName
[] = "org.chromium.leaderd";
23 const char kLeaderdObjectManagerServicePath
[] = "/org/chromium/leaderd";
24 const char kLeaderdManagerPath
[] = "/org/chromium/leaderd/Manager";
25 const char kManagerInterface
[] = "org.chromium.leaderd.Manager";
26 const char kGroupInterface
[] = "org.chromium.leaderd.Group";
27 const char kJoinGroupMethod
[] = "JoinGroup";
28 const char kLeaveGroupMethod
[] = "LeaveGroup";
29 const char kSetScoreMethod
[] = "SetScore";
30 const char kPokeLeaderMethod
[] = "PokeLeader";
31 const char kPingMethod
[] = "Ping";
32 const char kLeaderUUID
[] = "LeaderUUID";
33 const char kGroupMembers
[] = "GroupMembers";
34 } // namespace leaderd
38 // Since there is no property associated with Manager objects, an empty callback
40 void DoNothing(const std::string
& property_name
) {
43 // The LeadershipDaemonManagerClient implementation used in production.
44 class LeadershipDaemonManagerClientImpl
45 : public LeadershipDaemonManagerClient
,
46 public dbus::ObjectManager::Interface
{
48 LeadershipDaemonManagerClientImpl();
49 ~LeadershipDaemonManagerClientImpl() override
;
51 // LeadershipDaemonManagerClient overrides.
52 void AddObserver(Observer
* observer
) override
;
53 void RemoveObserver(Observer
* observer
) override
;
54 void JoinGroup(const std::string
& group
,
55 const base::DictionaryValue
& options
,
56 const StringDBusMethodCallback
& callback
) override
;
57 void LeaveGroup(const std::string
& object_path
,
58 const VoidDBusMethodCallback
& callback
) override
;
59 void SetScore(const std::string
& object_path
,
61 const VoidDBusMethodCallback
& callback
) override
;
62 void PokeLeader(const std::string
& object_path
,
63 const VoidDBusMethodCallback
& callback
) override
;
64 void Ping(const StringDBusMethodCallback
& callback
) override
;
65 const GroupProperties
* GetGroupProperties(
66 const dbus::ObjectPath
& object_path
) override
;
68 // DBusClient overrides.
69 void Init(dbus::Bus
* bus
) 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 // Called by dbus::PropertySet when a property value is changed,
83 // either by result of a signal or response to a GetAll() or Get()
84 // call. Informs observers.
85 void OnGroupPropertyChanged(const dbus::ObjectPath
& object_path
,
86 const std::string
& property_name
);
88 void OnStringDBusMethod(const StringDBusMethodCallback
& callback
,
89 dbus::Response
* response
);
90 void OnVoidDBusMethod(const VoidDBusMethodCallback
& callback
,
91 dbus::Response
* response
);
93 // List of observers interested in event notifications from us.
94 ObserverList
<Observer
> observers_
;
95 dbus::ObjectManager
* object_manager_
;
96 base::WeakPtrFactory
<LeadershipDaemonManagerClientImpl
> weak_ptr_factory_
;
98 DISALLOW_COPY_AND_ASSIGN(LeadershipDaemonManagerClientImpl
);
101 LeadershipDaemonManagerClientImpl::LeadershipDaemonManagerClientImpl()
102 : object_manager_(nullptr), weak_ptr_factory_(this) {
105 LeadershipDaemonManagerClientImpl::~LeadershipDaemonManagerClientImpl() {
106 if (object_manager_
) {
107 object_manager_
->UnregisterInterface(leaderd::kManagerInterface
);
108 object_manager_
->UnregisterInterface(leaderd::kGroupInterface
);
112 void LeadershipDaemonManagerClientImpl::AddObserver(Observer
* observer
) {
114 observers_
.AddObserver(observer
);
117 void LeadershipDaemonManagerClientImpl::RemoveObserver(Observer
* observer
) {
119 observers_
.RemoveObserver(observer
);
122 void LeadershipDaemonManagerClientImpl::JoinGroup(
123 const std::string
& group
,
124 const base::DictionaryValue
& options
,
125 const StringDBusMethodCallback
& callback
) {
126 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
127 dbus::ObjectPath(leaderd::kLeaderdManagerPath
));
129 base::MessageLoop::current()->PostTask(
131 base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod
,
132 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
136 dbus::MethodCall
method_call(leaderd::kManagerInterface
,
137 leaderd::kJoinGroupMethod
);
138 dbus::MessageWriter
writer(&method_call
);
139 writer
.AppendString(group
);
140 dbus::AppendValueData(&writer
, options
);
141 object_proxy
->CallMethod(
142 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
143 base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod
,
144 weak_ptr_factory_
.GetWeakPtr(), callback
));
147 void LeadershipDaemonManagerClientImpl::LeaveGroup(
148 const std::string
& object_path
,
149 const VoidDBusMethodCallback
& callback
) {
150 dbus::ObjectProxy
* object_proxy
=
151 object_manager_
->GetObjectProxy(dbus::ObjectPath(object_path
));
153 base::MessageLoop::current()->PostTask(
155 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod
,
156 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
160 dbus::MethodCall
method_call(leaderd::kGroupInterface
,
161 leaderd::kLeaveGroupMethod
);
162 dbus::MessageWriter
writer(&method_call
);
163 object_proxy
->CallMethod(
164 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
165 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod
,
166 weak_ptr_factory_
.GetWeakPtr(), callback
));
169 void LeadershipDaemonManagerClientImpl::SetScore(
170 const std::string
& object_path
,
172 const VoidDBusMethodCallback
& callback
) {
173 dbus::ObjectProxy
* object_proxy
=
174 object_manager_
->GetObjectProxy(dbus::ObjectPath(object_path
));
176 base::MessageLoop::current()->PostTask(
178 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod
,
179 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
183 dbus::MethodCall
method_call(leaderd::kGroupInterface
,
184 leaderd::kSetScoreMethod
);
185 dbus::MessageWriter
writer(&method_call
);
186 writer
.AppendInt32(score
);
187 object_proxy
->CallMethod(
188 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
189 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod
,
190 weak_ptr_factory_
.GetWeakPtr(), callback
));
193 void LeadershipDaemonManagerClientImpl::PokeLeader(
194 const std::string
& object_path
,
195 const VoidDBusMethodCallback
& callback
) {
196 dbus::ObjectProxy
* object_proxy
=
197 object_manager_
->GetObjectProxy(dbus::ObjectPath(object_path
));
199 base::MessageLoop::current()->PostTask(
201 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod
,
202 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
206 dbus::MethodCall
method_call(leaderd::kGroupInterface
,
207 leaderd::kPokeLeaderMethod
);
208 dbus::MessageWriter
writer(&method_call
);
209 object_proxy
->CallMethod(
210 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
211 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod
,
212 weak_ptr_factory_
.GetWeakPtr(), callback
));
215 void LeadershipDaemonManagerClientImpl::Ping(
216 const StringDBusMethodCallback
& callback
) {
217 dbus::ObjectProxy
* object_proxy
= object_manager_
->GetObjectProxy(
218 dbus::ObjectPath(leaderd::kLeaderdManagerPath
));
220 base::MessageLoop::current()->PostTask(
222 base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod
,
223 weak_ptr_factory_
.GetWeakPtr(), callback
, nullptr));
227 dbus::MethodCall
method_call(leaderd::kManagerInterface
,
228 leaderd::kPingMethod
);
229 dbus::MessageWriter
writer(&method_call
);
230 object_proxy
->CallMethod(
231 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
232 base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod
,
233 weak_ptr_factory_
.GetWeakPtr(), callback
));
236 const LeadershipDaemonManagerClient::GroupProperties
*
237 LeadershipDaemonManagerClientImpl::GetGroupProperties(
238 const dbus::ObjectPath
& object_path
) {
239 return static_cast<GroupProperties
*>(
240 object_manager_
->GetProperties(object_path
, leaderd::kGroupInterface
));
243 void LeadershipDaemonManagerClientImpl::Init(dbus::Bus
* bus
) {
244 object_manager_
= bus
->GetObjectManager(
245 leaderd::kLeaderdServiceName
,
246 dbus::ObjectPath(leaderd::kLeaderdObjectManagerServicePath
));
247 object_manager_
->RegisterInterface(leaderd::kManagerInterface
, this);
248 object_manager_
->RegisterInterface(leaderd::kGroupInterface
, this);
251 dbus::PropertySet
* LeadershipDaemonManagerClientImpl::CreateProperties(
252 dbus::ObjectProxy
* object_proxy
,
253 const dbus::ObjectPath
& object_path
,
254 const std::string
& interface_name
) {
255 dbus::PropertySet
* properties
= nullptr;
256 if (interface_name
== leaderd::kManagerInterface
) {
257 properties
= new dbus::PropertySet(object_proxy
, interface_name
,
258 base::Bind(&DoNothing
));
259 } else if (interface_name
== leaderd::kGroupInterface
) {
260 properties
= new GroupProperties(
261 object_proxy
, interface_name
,
262 base::Bind(&LeadershipDaemonManagerClientImpl::OnGroupPropertyChanged
,
263 weak_ptr_factory_
.GetWeakPtr(), object_path
));
265 NOTREACHED() << "Unhandled interface name " << interface_name
;
270 void LeadershipDaemonManagerClientImpl::ObjectAdded(
271 const dbus::ObjectPath
& object_path
,
272 const std::string
& interface_name
) {
273 if (interface_name
== leaderd::kManagerInterface
) {
274 FOR_EACH_OBSERVER(Observer
, observers_
, ManagerAdded());
275 } else if (interface_name
== leaderd::kGroupInterface
) {
276 FOR_EACH_OBSERVER(Observer
, observers_
, GroupAdded(object_path
));
278 NOTREACHED() << "Unhandled interface name " << interface_name
;
282 void LeadershipDaemonManagerClientImpl::ObjectRemoved(
283 const dbus::ObjectPath
& object_path
,
284 const std::string
& interface_name
) {
285 if (interface_name
== leaderd::kManagerInterface
) {
286 FOR_EACH_OBSERVER(Observer
, observers_
, ManagerRemoved());
287 } else if (interface_name
== leaderd::kGroupInterface
) {
288 FOR_EACH_OBSERVER(Observer
, observers_
, GroupRemoved(object_path
));
290 NOTREACHED() << "Unhandled interface name " << interface_name
;
294 void LeadershipDaemonManagerClientImpl::OnGroupPropertyChanged(
295 const dbus::ObjectPath
& object_path
,
296 const std::string
& property_name
) {
297 FOR_EACH_OBSERVER(Observer
, observers_
,
298 GroupPropertyChanged(object_path
, property_name
));
301 void LeadershipDaemonManagerClientImpl::OnStringDBusMethod(
302 const StringDBusMethodCallback
& callback
,
303 dbus::Response
* response
) {
305 callback
.Run(DBUS_METHOD_CALL_FAILURE
, std::string());
309 dbus::MessageReader
reader(response
);
311 if (!reader
.PopString(&result
)) {
312 callback
.Run(DBUS_METHOD_CALL_FAILURE
, std::string());
316 callback
.Run(DBUS_METHOD_CALL_SUCCESS
, result
);
319 void LeadershipDaemonManagerClientImpl::OnVoidDBusMethod(
320 const VoidDBusMethodCallback
& callback
,
321 dbus::Response
* response
) {
322 callback
.Run(response
? DBUS_METHOD_CALL_SUCCESS
: DBUS_METHOD_CALL_FAILURE
);
327 LeadershipDaemonManagerClient::GroupProperties::GroupProperties(
328 dbus::ObjectProxy
* object_proxy
,
329 const std::string
& interface_name
,
330 const PropertyChangedCallback
& callback
)
331 : dbus::PropertySet(object_proxy
, interface_name
, callback
) {
332 RegisterProperty(leaderd::kLeaderUUID
, &leader_uuid_
);
333 RegisterProperty(leaderd::kGroupMembers
, &group_members_
);
336 LeadershipDaemonManagerClient::GroupProperties::~GroupProperties() {
339 LeadershipDaemonManagerClient::Observer::~Observer() {
342 void LeadershipDaemonManagerClient::Observer::ManagerAdded() {
345 void LeadershipDaemonManagerClient::Observer::ManagerRemoved() {
348 void LeadershipDaemonManagerClient::Observer::GroupAdded(
349 const dbus::ObjectPath
& object_path
) {
352 void LeadershipDaemonManagerClient::Observer::GroupRemoved(
353 const dbus::ObjectPath
& object_path
) {
356 void LeadershipDaemonManagerClient::Observer::GroupPropertyChanged(
357 const dbus::ObjectPath
& object_path
,
358 const std::string
& property_name
) {
361 LeadershipDaemonManagerClient::LeadershipDaemonManagerClient() {
364 LeadershipDaemonManagerClient::~LeadershipDaemonManagerClient() {
368 LeadershipDaemonManagerClient
* LeadershipDaemonManagerClient::Create() {
369 return new LeadershipDaemonManagerClientImpl();
372 } // namespace chromeos