OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 #include "chromeos/dbus/leadership_daemon_manager_client.h" | |
6 | |
7 #include "base/bind.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" | |
13 #include "dbus/bus.h" | |
14 #include "dbus/message.h" | |
15 #include "dbus/object_manager.h" | |
16 #include "dbus/object_proxy.h" | |
17 #include "dbus/values_util.h" | |
18 | |
19 namespace chromeos { | |
20 | |
21 // TODO(benchan): Move these constants to system_api. | |
22 namespace leaderd { | |
23 const char kLeaderdServiceName[] = "org.chromium.leaderd"; | |
24 const char kLeaderdObjectManagerServicePath[] = "/org/chromium/leaderd"; | |
25 const char kLeaderdManagerPath[] = "/org/chromium/leaderd/Manager"; | |
26 const char kManagerInterface[] = "org.chromium.leaderd.Manager"; | |
27 const char kGroupInterface[] = "org.chromium.leaderd.Group"; | |
28 const char kJoinGroupMethod[] = "JoinGroup"; | |
29 const char kLeaveGroupMethod[] = "LeaveGroup"; | |
30 const char kSetScoreMethod[] = "SetScore"; | |
31 const char kPokeLeaderMethod[] = "PokeLeader"; | |
32 const char kPingMethod[] = "Ping"; | |
33 const char kLeaderUUID[] = "LeaderUUID"; | |
34 const char kGroupMembers[] = "GroupMembers"; | |
35 } // namespace leaderd | |
36 | |
37 namespace { | |
38 | |
39 // Since there is no property associated with Manager objects, an empty callback | |
40 // is used. | |
41 void DoNothing(const std::string& property_name) { | |
42 } | |
43 | |
44 // The LeadershipDaemonManagerClient implementation used in production. | |
45 class LeadershipDaemonManagerClientImpl | |
46 : public LeadershipDaemonManagerClient, | |
47 public dbus::ObjectManager::Interface { | |
48 public: | |
49 LeadershipDaemonManagerClientImpl(); | |
50 ~LeadershipDaemonManagerClientImpl() override; | |
51 | |
52 // LeadershipDaemonManagerClient overrides. | |
53 void AddObserver(Observer* observer) override; | |
54 void RemoveObserver(Observer* observer) override; | |
55 void JoinGroup(const std::string& group, | |
56 const base::DictionaryValue& options, | |
57 const StringDBusMethodCallback& callback) override; | |
58 void LeaveGroup(const std::string& object_path, | |
59 const VoidDBusMethodCallback& callback) override; | |
60 void SetScore(const std::string& object_path, | |
61 int score, | |
62 const VoidDBusMethodCallback& callback) override; | |
63 void PokeLeader(const std::string& object_path, | |
64 const VoidDBusMethodCallback& callback) override; | |
65 void Ping(const StringDBusMethodCallback& callback) override; | |
66 const GroupProperties* GetGroupProperties( | |
67 const dbus::ObjectPath& object_path) override; | |
68 | |
69 // DBusClient overrides. | |
70 void Init(dbus::Bus* bus) override; | |
71 | |
72 // dbus::ObjectManager::Interface override. | |
stevenjb
2015/02/13 18:53:19
nit: overrides
| |
73 dbus::PropertySet* CreateProperties( | |
74 dbus::ObjectProxy* object_proxy, | |
75 const dbus::ObjectPath& object_path, | |
76 const std::string& interface_name) override; | |
77 void ObjectAdded(const dbus::ObjectPath& object_path, | |
78 const std::string& interface_name) override; | |
79 void ObjectRemoved(const dbus::ObjectPath& object_path, | |
80 const std::string& interface_name) override; | |
81 | |
82 private: | |
83 // Called by dbus::PropertySet when a property value is changed, | |
84 // either by result of a signal or response to a GetAll() or Get() | |
85 // call. Informs observers. | |
86 void OnGroupPropertyChanged(const dbus::ObjectPath& object_path, | |
87 const std::string& property_name); | |
88 | |
89 void OnStringDBusMethod(const StringDBusMethodCallback& callback, | |
90 dbus::Response* response); | |
91 void OnVoidDBusMethod(const VoidDBusMethodCallback& callback, | |
92 dbus::Response* response); | |
93 | |
94 // List of observers interested in event notifications from us. | |
95 ObserverList<Observer> observers_; | |
96 dbus::ObjectManager* object_manager_; | |
97 base::WeakPtrFactory<LeadershipDaemonManagerClientImpl> weak_ptr_factory_; | |
98 | |
99 DISALLOW_COPY_AND_ASSIGN(LeadershipDaemonManagerClientImpl); | |
100 }; | |
101 | |
102 LeadershipDaemonManagerClientImpl::LeadershipDaemonManagerClientImpl() | |
103 : object_manager_(nullptr), weak_ptr_factory_(this) { | |
104 } | |
105 | |
106 LeadershipDaemonManagerClientImpl::~LeadershipDaemonManagerClientImpl() { | |
107 if (object_manager_) { | |
108 object_manager_->UnregisterInterface(leaderd::kManagerInterface); | |
109 object_manager_->UnregisterInterface(leaderd::kGroupInterface); | |
110 } | |
111 } | |
112 | |
113 void LeadershipDaemonManagerClientImpl::AddObserver(Observer* observer) { | |
114 DCHECK(observer); | |
115 observers_.AddObserver(observer); | |
116 } | |
117 | |
118 void LeadershipDaemonManagerClientImpl::RemoveObserver(Observer* observer) { | |
119 DCHECK(observer); | |
120 observers_.RemoveObserver(observer); | |
121 } | |
122 | |
123 void LeadershipDaemonManagerClientImpl::JoinGroup( | |
124 const std::string& group, | |
125 const base::DictionaryValue& options, | |
126 const StringDBusMethodCallback& callback) { | |
127 dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy( | |
128 dbus::ObjectPath(leaderd::kLeaderdManagerPath)); | |
129 if (!object_proxy) { | |
130 base::MessageLoop::current()->PostTask( | |
131 FROM_HERE, | |
132 base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod, | |
133 weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); | |
134 return; | |
135 } | |
136 | |
137 dbus::MethodCall method_call(leaderd::kManagerInterface, | |
138 leaderd::kJoinGroupMethod); | |
139 dbus::MessageWriter writer(&method_call); | |
140 writer.AppendString(group); | |
141 dbus::AppendValueData(&writer, options); | |
142 object_proxy->CallMethod( | |
143 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
144 base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod, | |
145 weak_ptr_factory_.GetWeakPtr(), callback)); | |
146 } | |
147 | |
148 void LeadershipDaemonManagerClientImpl::LeaveGroup( | |
149 const std::string& object_path, | |
150 const VoidDBusMethodCallback& callback) { | |
151 dbus::ObjectProxy* object_proxy = | |
152 object_manager_->GetObjectProxy(dbus::ObjectPath(object_path)); | |
153 if (!object_proxy) { | |
154 base::MessageLoop::current()->PostTask( | |
155 FROM_HERE, | |
156 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, | |
157 weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); | |
158 return; | |
159 } | |
160 | |
161 dbus::MethodCall method_call(leaderd::kGroupInterface, | |
162 leaderd::kLeaveGroupMethod); | |
163 dbus::MessageWriter writer(&method_call); | |
164 object_proxy->CallMethod( | |
165 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
166 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, | |
167 weak_ptr_factory_.GetWeakPtr(), callback)); | |
168 } | |
169 | |
170 void LeadershipDaemonManagerClientImpl::SetScore( | |
171 const std::string& object_path, | |
172 int score, | |
173 const VoidDBusMethodCallback& callback) { | |
174 dbus::ObjectProxy* object_proxy = | |
175 object_manager_->GetObjectProxy(dbus::ObjectPath(object_path)); | |
176 if (!object_proxy) { | |
177 base::MessageLoop::current()->PostTask( | |
178 FROM_HERE, | |
179 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, | |
180 weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); | |
181 return; | |
182 } | |
183 | |
184 dbus::MethodCall method_call(leaderd::kGroupInterface, | |
185 leaderd::kSetScoreMethod); | |
186 dbus::MessageWriter writer(&method_call); | |
187 writer.AppendInt32(score); | |
188 object_proxy->CallMethod( | |
189 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
190 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, | |
191 weak_ptr_factory_.GetWeakPtr(), callback)); | |
192 } | |
193 | |
194 void LeadershipDaemonManagerClientImpl::PokeLeader( | |
195 const std::string& object_path, | |
196 const VoidDBusMethodCallback& callback) { | |
197 dbus::ObjectProxy* object_proxy = | |
198 object_manager_->GetObjectProxy(dbus::ObjectPath(object_path)); | |
199 if (!object_proxy) { | |
200 base::MessageLoop::current()->PostTask( | |
201 FROM_HERE, | |
202 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, | |
203 weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); | |
204 return; | |
205 } | |
206 | |
207 dbus::MethodCall method_call(leaderd::kGroupInterface, | |
208 leaderd::kPokeLeaderMethod); | |
209 dbus::MessageWriter writer(&method_call); | |
210 object_proxy->CallMethod( | |
211 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
212 base::Bind(&LeadershipDaemonManagerClientImpl::OnVoidDBusMethod, | |
213 weak_ptr_factory_.GetWeakPtr(), callback)); | |
214 } | |
215 | |
216 void LeadershipDaemonManagerClientImpl::Ping( | |
217 const StringDBusMethodCallback& callback) { | |
218 dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy( | |
219 dbus::ObjectPath(leaderd::kLeaderdManagerPath)); | |
220 if (!object_proxy) { | |
221 base::MessageLoop::current()->PostTask( | |
222 FROM_HERE, | |
223 base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod, | |
224 weak_ptr_factory_.GetWeakPtr(), callback, nullptr)); | |
225 return; | |
226 } | |
227 | |
228 dbus::MethodCall method_call(leaderd::kManagerInterface, | |
229 leaderd::kPingMethod); | |
230 dbus::MessageWriter writer(&method_call); | |
231 object_proxy->CallMethod( | |
232 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
233 base::Bind(&LeadershipDaemonManagerClientImpl::OnStringDBusMethod, | |
234 weak_ptr_factory_.GetWeakPtr(), callback)); | |
235 } | |
236 | |
237 const LeadershipDaemonManagerClient::GroupProperties* | |
238 LeadershipDaemonManagerClientImpl::GetGroupProperties( | |
239 const dbus::ObjectPath& object_path) { | |
240 return static_cast<GroupProperties*>( | |
241 object_manager_->GetProperties(object_path, leaderd::kGroupInterface)); | |
242 } | |
243 | |
244 void LeadershipDaemonManagerClientImpl::Init(dbus::Bus* bus) { | |
245 object_manager_ = bus->GetObjectManager( | |
246 leaderd::kLeaderdServiceName, | |
247 dbus::ObjectPath(leaderd::kLeaderdObjectManagerServicePath)); | |
248 object_manager_->RegisterInterface(leaderd::kManagerInterface, this); | |
249 object_manager_->RegisterInterface(leaderd::kGroupInterface, this); | |
250 } | |
251 | |
252 dbus::PropertySet* LeadershipDaemonManagerClientImpl::CreateProperties( | |
253 dbus::ObjectProxy* object_proxy, | |
254 const dbus::ObjectPath& object_path, | |
255 const std::string& interface_name) { | |
256 dbus::PropertySet* properties = nullptr; | |
257 if (interface_name == leaderd::kManagerInterface) { | |
258 properties = new dbus::PropertySet(object_proxy, interface_name, | |
259 base::Bind(&DoNothing)); | |
260 } else if (interface_name == leaderd::kGroupInterface) { | |
261 properties = new GroupProperties( | |
262 object_proxy, interface_name, | |
263 base::Bind(&LeadershipDaemonManagerClientImpl::OnGroupPropertyChanged, | |
264 weak_ptr_factory_.GetWeakPtr(), object_path)); | |
265 } else { | |
266 NOTREACHED() << "Unhandled interface name " << interface_name; | |
267 } | |
268 return properties; | |
269 } | |
270 | |
271 void LeadershipDaemonManagerClientImpl::ObjectAdded( | |
272 const dbus::ObjectPath& object_path, | |
273 const std::string& interface_name) { | |
274 if (interface_name == leaderd::kManagerInterface) { | |
275 FOR_EACH_OBSERVER(Observer, observers_, ManagerAdded()); | |
276 } else if (interface_name == leaderd::kGroupInterface) { | |
277 FOR_EACH_OBSERVER(Observer, observers_, GroupAdded(object_path)); | |
278 } else { | |
279 NOTREACHED() << "Unhandled interface name " << interface_name; | |
280 } | |
281 } | |
282 | |
283 void LeadershipDaemonManagerClientImpl::ObjectRemoved( | |
284 const dbus::ObjectPath& object_path, | |
285 const std::string& interface_name) { | |
286 if (interface_name == leaderd::kManagerInterface) { | |
287 FOR_EACH_OBSERVER(Observer, observers_, ManagerRemoved()); | |
288 } else if (interface_name == leaderd::kGroupInterface) { | |
289 FOR_EACH_OBSERVER(Observer, observers_, GroupRemoved(object_path)); | |
290 } else { | |
291 NOTREACHED() << "Unhandled interface name " << interface_name; | |
292 } | |
293 } | |
294 | |
295 void LeadershipDaemonManagerClientImpl::OnGroupPropertyChanged( | |
296 const dbus::ObjectPath& object_path, | |
297 const std::string& property_name) { | |
298 FOR_EACH_OBSERVER(Observer, observers_, | |
299 GroupPropertyChanged(object_path, property_name)); | |
300 } | |
301 | |
302 void LeadershipDaemonManagerClientImpl::OnStringDBusMethod( | |
303 const StringDBusMethodCallback& callback, | |
304 dbus::Response* response) { | |
305 if (!response) { | |
306 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string()); | |
307 return; | |
308 } | |
309 | |
310 dbus::MessageReader reader(response); | |
311 std::string result; | |
312 if (!reader.PopString(&result)) { | |
313 callback.Run(DBUS_METHOD_CALL_FAILURE, std::string()); | |
314 return; | |
315 } | |
316 | |
317 callback.Run(DBUS_METHOD_CALL_SUCCESS, result); | |
318 } | |
319 | |
320 void LeadershipDaemonManagerClientImpl::OnVoidDBusMethod( | |
321 const VoidDBusMethodCallback& callback, | |
322 dbus::Response* response) { | |
323 callback.Run(response ? DBUS_METHOD_CALL_SUCCESS : DBUS_METHOD_CALL_FAILURE); | |
324 } | |
325 | |
326 } // namespace | |
327 | |
328 LeadershipDaemonManagerClient::GroupProperties::GroupProperties( | |
329 dbus::ObjectProxy* object_proxy, | |
330 const std::string& interface_name, | |
331 const PropertyChangedCallback& callback) | |
332 : dbus::PropertySet(object_proxy, interface_name, callback) { | |
333 RegisterProperty(leaderd::kLeaderUUID, &leader_uuid_); | |
334 RegisterProperty(leaderd::kGroupMembers, &group_members_); | |
335 } | |
336 | |
337 LeadershipDaemonManagerClient::GroupProperties::~GroupProperties() { | |
338 } | |
339 | |
340 LeadershipDaemonManagerClient::Observer::~Observer() { | |
341 } | |
342 | |
343 void LeadershipDaemonManagerClient::Observer::ManagerAdded() { | |
344 } | |
345 | |
346 void LeadershipDaemonManagerClient::Observer::ManagerRemoved() { | |
347 } | |
348 | |
349 void LeadershipDaemonManagerClient::Observer::GroupAdded( | |
350 const dbus::ObjectPath& object_path) { | |
351 } | |
352 | |
353 void LeadershipDaemonManagerClient::Observer::GroupRemoved( | |
354 const dbus::ObjectPath& object_path) { | |
355 } | |
356 | |
357 void LeadershipDaemonManagerClient::Observer::GroupPropertyChanged( | |
358 const dbus::ObjectPath& object_path, | |
359 const std::string& property_name) { | |
360 } | |
361 | |
362 LeadershipDaemonManagerClient::LeadershipDaemonManagerClient() { | |
363 } | |
364 | |
365 LeadershipDaemonManagerClient::~LeadershipDaemonManagerClient() { | |
366 } | |
367 | |
368 // static | |
369 LeadershipDaemonManagerClient* LeadershipDaemonManagerClient::Create() { | |
370 return new LeadershipDaemonManagerClientImpl(); | |
371 } | |
372 | |
373 } // namespace chromeos | |
OLD | NEW |