Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: chromeos/dbus/experimental_bluetooth_device_client.cc

Issue 12605008: D-Bus Clients for BlueZ 5 API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: mock dbus thread manager without gmock? I didn't even know that was a thing! Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 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/experimental_bluetooth_device_client.h"
6
7 #include <map>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/logging.h"
12 #include "base/stl_util.h"
13 #include "chromeos/dbus/bluetooth_property.h"
14 #include "dbus/bus.h"
15 #include "dbus/message.h"
16 #include "dbus/object_manager.h"
17 #include "dbus/object_path.h"
18 #include "dbus/object_proxy.h"
19 #include "third_party/cros_system_api/dbus/service_constants.h"
20
21 namespace chromeos {
22
23 const char ExperimentalBluetoothDeviceClient::kNoResponseError[] =
24 "org.chromium.Error.NoResponse";
25 const char ExperimentalBluetoothDeviceClient::kUnknownDeviceError[] =
26 "org.chromium.Error.UnknownDevice";
27
28 ExperimentalBluetoothDeviceClient::Properties::Properties(
29 dbus::ObjectProxy* object_proxy,
30 const std::string& interface_name,
31 const PropertyChangedCallback& callback)
32 : dbus::PropertySet(object_proxy, interface_name, callback) {
33 RegisterProperty(bluetooth_device::kAddressProperty, &address);
34 RegisterProperty(bluetooth_device::kNameProperty, &name);
35 RegisterProperty(bluetooth_device::kIconProperty, &icon);
36 RegisterProperty(bluetooth_device::kClassProperty, &bluetooth_class);
37 RegisterProperty(bluetooth_device::kAppearanceProperty, &appearance);
38 RegisterProperty(bluetooth_device::kUUIDsProperty, &uuids);
39 RegisterProperty(bluetooth_device::kPairedProperty, &paired);
40 RegisterProperty(bluetooth_device::kConnectedProperty, &connected);
41 RegisterProperty(bluetooth_device::kTrustedProperty, &trusted);
42 RegisterProperty(bluetooth_device::kBlockedProperty, &blocked);
43 RegisterProperty(bluetooth_device::kAliasProperty, &alias);
44 RegisterProperty(bluetooth_device::kAdapterProperty, &adapter);
45 RegisterProperty(bluetooth_device::kLegacyPairingProperty, &legacy_pairing);
46 RegisterProperty(bluetooth_device::kModaliasProperty, &modalias);
47 RegisterProperty(bluetooth_device::kRSSIProperty, &rssi);
48 }
49
50 ExperimentalBluetoothDeviceClient::Properties::~Properties() {
51 }
52
53
54 // The ExperimentalBluetoothDeviceClient implementation used in production.
55 class ExperimentalBluetoothDeviceClientImpl
56 : public ExperimentalBluetoothDeviceClient,
57 public dbus::ObjectManager::Interface {
58 public:
59 explicit ExperimentalBluetoothDeviceClientImpl(dbus::Bus* bus)
60 : bus_(bus),
61 weak_ptr_factory_(this) {
62 object_manager_ = bus_->GetObjectManager(
63 bluetooth_manager::kBluetoothManagerServiceName,
64 dbus::ObjectPath(bluetooth_manager::kBluetoothManagerServicePath));
65 object_manager_->RegisterInterface(
66 bluetooth_device::kExperimentalBluetoothDeviceInterface, this);
67 }
68
69 virtual ~ExperimentalBluetoothDeviceClientImpl() {
70 object_manager_->UnregisterInterface(
71 bluetooth_device::kExperimentalBluetoothDeviceInterface);
72 }
73
74 // ExperimentalBluetoothDeviceClient override.
75 virtual void AddObserver(
76 ExperimentalBluetoothDeviceClient::Observer* observer) OVERRIDE {
77 DCHECK(observer);
78 observers_.AddObserver(observer);
79 }
80
81 // ExperimentalBluetoothDeviceClient override.
82 virtual void RemoveObserver(
83 ExperimentalBluetoothDeviceClient::Observer* observer) OVERRIDE {
84 DCHECK(observer);
85 observers_.RemoveObserver(observer);
86 }
87
88 // dbus::ObjectManager::Interface override.
89 virtual dbus::PropertySet* CreateProperties(
90 dbus::ObjectProxy* object_proxy,
91 const dbus::ObjectPath& object_path,
92 const std::string& interface_name) {
93 Properties* properties = new Properties(
94 object_proxy, interface_name,
95 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnPropertyChanged,
96 weak_ptr_factory_.GetWeakPtr(),
97 object_path));
98 return static_cast<dbus::PropertySet*>(properties);
99 }
100
101 // ExperimentalBluetoothDeviceClient override.
102 virtual std::vector<dbus::ObjectPath> GetDevicesForAdapter(
103 const dbus::ObjectPath& adapter_path) OVERRIDE {
104 std::vector<dbus::ObjectPath> object_paths, device_paths;
105 device_paths = object_manager_->GetObjectsWithInterface(
106 bluetooth_device::kExperimentalBluetoothDeviceInterface);
107 for (std::vector<dbus::ObjectPath>::iterator iter = device_paths.begin();
108 iter != device_paths.end(); ++iter) {
109 Properties* properties = GetProperties(*iter);
110 if (properties->adapter.value() == adapter_path)
111 object_paths.push_back(*iter);
112 }
113 return object_paths;
114 }
115
116 // ExperimentalBluetoothDeviceClient override.
117 virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
118 OVERRIDE {
119 return static_cast<Properties*>(
120 object_manager_->GetProperties(
121 object_path,
122 bluetooth_device::kExperimentalBluetoothDeviceInterface));
123 }
124
125 // ExperimentalBluetoothDeviceClient override.
126 virtual void Connect(const dbus::ObjectPath& object_path,
127 const base::Closure& callback,
128 const ErrorCallback& error_callback) OVERRIDE {
129 dbus::MethodCall method_call(
130 bluetooth_device::kExperimentalBluetoothDeviceInterface,
131 bluetooth_device::kConnect);
132
133 dbus::ObjectProxy* object_proxy =
134 object_manager_->GetObjectProxy(object_path);
135 if (!object_proxy) {
136 error_callback.Run(kUnknownDeviceError, "");
137 return;
138 }
139
140 // Connect may take an arbitrary length of time, so use no timeout.
141 object_proxy->CallMethodWithErrorCallback(
142 &method_call,
143 dbus::ObjectProxy::TIMEOUT_INFINITE,
144 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess,
145 weak_ptr_factory_.GetWeakPtr(), callback),
146 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError,
147 weak_ptr_factory_.GetWeakPtr(), error_callback));
148 }
149
150 // ExperimentalBluetoothDeviceClient override.
151 virtual void Disconnect(const dbus::ObjectPath& object_path,
152 const base::Closure& callback,
153 const ErrorCallback& error_callback) OVERRIDE {
154 dbus::MethodCall method_call(
155 bluetooth_device::kExperimentalBluetoothDeviceInterface,
156 bluetooth_device::kDisconnect);
157
158 dbus::ObjectProxy* object_proxy =
159 object_manager_->GetObjectProxy(object_path);
160 if (!object_proxy) {
161 error_callback.Run(kUnknownDeviceError, "");
162 return;
163 }
164
165 object_proxy->CallMethodWithErrorCallback(
166 &method_call,
167 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
168 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess,
169 weak_ptr_factory_.GetWeakPtr(), callback),
170 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError,
171 weak_ptr_factory_.GetWeakPtr(), error_callback));
172 }
173
174 // ExperimentalBluetoothDeviceClient override.
175 virtual void ConnectProfile(const dbus::ObjectPath& object_path,
176 const std::string& uuid,
177 const base::Closure& callback,
178 const ErrorCallback& error_callback) OVERRIDE {
179 dbus::MethodCall method_call(
180 bluetooth_device::kExperimentalBluetoothDeviceInterface,
181 bluetooth_device::kConnectProfile);
182
183 dbus::MessageWriter writer(&method_call);
184 writer.AppendString(uuid);
185
186 dbus::ObjectProxy* object_proxy =
187 object_manager_->GetObjectProxy(object_path);
188 if (!object_proxy) {
189 error_callback.Run(kUnknownDeviceError, "");
190 return;
191 }
192
193 // Connect may take an arbitrary length of time, so use no timeout.
194 object_proxy->CallMethodWithErrorCallback(
195 &method_call,
196 dbus::ObjectProxy::TIMEOUT_INFINITE,
197 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess,
198 weak_ptr_factory_.GetWeakPtr(), callback),
199 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError,
200 weak_ptr_factory_.GetWeakPtr(), error_callback));
201 }
202
203 // ExperimentalBluetoothDeviceClient override.
204 virtual void DisconnectProfile(const dbus::ObjectPath& object_path,
205 const std::string& uuid,
206 const base::Closure& callback,
207 const ErrorCallback& error_callback)
208 OVERRIDE {
209 dbus::MethodCall method_call(
210 bluetooth_device::kExperimentalBluetoothDeviceInterface,
211 bluetooth_device::kDisconnectProfile);
212
213 dbus::MessageWriter writer(&method_call);
214 writer.AppendString(uuid);
215
216 dbus::ObjectProxy* object_proxy =
217 object_manager_->GetObjectProxy(object_path);
218 if (!object_proxy) {
219 error_callback.Run(kUnknownDeviceError, "");
220 return;
221 }
222
223 object_proxy->CallMethodWithErrorCallback(
224 &method_call,
225 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
226 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess,
227 weak_ptr_factory_.GetWeakPtr(), callback),
228 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError,
229 weak_ptr_factory_.GetWeakPtr(), error_callback));
230 }
231
232 // ExperimentalBluetoothDeviceClient override.
233 virtual void Pair(const dbus::ObjectPath& object_path,
234 const base::Closure& callback,
235 const ErrorCallback& error_callback) OVERRIDE {
236 dbus::MethodCall method_call(
237 bluetooth_device::kExperimentalBluetoothDeviceInterface,
238 bluetooth_device::kPair);
239
240 dbus::ObjectProxy* object_proxy =
241 object_manager_->GetObjectProxy(object_path);
242 if (!object_proxy) {
243 error_callback.Run(kUnknownDeviceError, "");
244 return;
245 }
246
247 // Pairing may take an arbitrary length of time, so use no timeout.
248 object_proxy->CallMethodWithErrorCallback(
249 &method_call,
250 dbus::ObjectProxy::TIMEOUT_INFINITE,
251 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess,
252 weak_ptr_factory_.GetWeakPtr(), callback),
253 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError,
254 weak_ptr_factory_.GetWeakPtr(), error_callback));
255 }
256
257 // ExperimentalBluetoothDeviceClient override.
258 virtual void CancelPairing(const dbus::ObjectPath& object_path,
259 const base::Closure& callback,
260 const ErrorCallback& error_callback)
261 OVERRIDE {
262 dbus::MethodCall method_call(
263 bluetooth_device::kExperimentalBluetoothDeviceInterface,
264 bluetooth_device::kCancelPairing);
265
266 dbus::ObjectProxy* object_proxy =
267 object_manager_->GetObjectProxy(object_path);
268 if (!object_proxy) {
269 error_callback.Run(kUnknownDeviceError, "");
270 return;
271 }
272 object_proxy->CallMethodWithErrorCallback(
273 &method_call,
274 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
275 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnSuccess,
276 weak_ptr_factory_.GetWeakPtr(), callback),
277 base::Bind(&ExperimentalBluetoothDeviceClientImpl::OnError,
278 weak_ptr_factory_.GetWeakPtr(), error_callback));
279 }
280
281 private:
282 // Called by dbus::ObjectManager when an object with the device interface
283 // is created. Informs observers.
284 void ObjectAdded(const dbus::ObjectPath& object_path,
285 const std::string& interface_name) OVERRIDE {
286 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_,
287 DeviceAdded(object_path));
288 }
289
290 // Called by dbus::ObjectManager when an object with the device interface
291 // is removed. Informs observers.
292 void ObjectRemoved(const dbus::ObjectPath& object_path,
293 const std::string& interface_name) OVERRIDE {
294 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_,
295 DeviceRemoved(object_path));
296 }
297
298 // Called by BluetoothPropertySet when a property value is changed,
299 // either by result of a signal or response to a GetAll() or Get()
300 // call. Informs observers.
301 void OnPropertyChanged(const dbus::ObjectPath& object_path,
302 const std::string& property_name) {
303 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_,
304 DevicePropertyChanged(object_path, property_name));
305 }
306
307 // Called when a response for successful method call is received.
308 void OnSuccess(const base::Closure& callback,
309 dbus::Response* response) {
310 DCHECK(response);
311 callback.Run();
312 }
313
314 // Called when a response for a failed method call is received.
315 void OnError(const ErrorCallback& error_callback,
316 dbus::ErrorResponse* response) {
317 // Error response has optional error message argument.
318 std::string error_name;
319 std::string error_message;
320 if (response) {
321 dbus::MessageReader reader(response);
322 error_name = response->GetErrorName();
323 reader.PopString(&error_message);
324 } else {
325 error_name = kNoResponseError;
326 error_message = "";
327 }
328 error_callback.Run(error_name, error_message);
329 }
330
331 dbus::Bus* bus_;
332 dbus::ObjectManager* object_manager_;
333
334 // List of observers interested in event notifications from us.
335 ObserverList<ExperimentalBluetoothDeviceClient::Observer> observers_;
336
337 // Weak pointer factory for generating 'this' pointers that might live longer
338 // than we do.
339 // Note: This should remain the last member so it'll be destroyed and
340 // invalidate its weak pointers before any other members are destroyed.
341 base::WeakPtrFactory<ExperimentalBluetoothDeviceClientImpl> weak_ptr_factory_;
342
343 DISALLOW_COPY_AND_ASSIGN(ExperimentalBluetoothDeviceClientImpl);
344 };
345
346 // The ExperimentalBluetoothDeviceClient implementation used on Linux desktop,
347 // which does nothing.
348 class ExperimentalBluetoothDeviceClientStubImpl
349 : public ExperimentalBluetoothDeviceClient {
350 public:
351 struct Properties : public ExperimentalBluetoothDeviceClient::Properties {
352 explicit Properties(const PropertyChangedCallback& callback)
353 : ExperimentalBluetoothDeviceClient::Properties(
354 NULL,
355 bluetooth_device::kExperimentalBluetoothDeviceInterface,
356 callback) {
357 }
358
359 virtual ~Properties() {
360 }
361
362 virtual void Get(dbus::PropertyBase* property,
363 dbus::PropertySet::GetCallback callback) OVERRIDE {
364 VLOG(1) << "Get " << property->name();
365 callback.Run(false);
366 }
367
368 virtual void GetAll() OVERRIDE {
369 VLOG(1) << "GetAll";
370 }
371
372 virtual void Set(dbus::PropertyBase *property,
373 dbus::PropertySet::SetCallback callback) OVERRIDE {
374 VLOG(1) << "Set " << property->name();
375 callback.Run(false);
376 }
377 };
378
379 ExperimentalBluetoothDeviceClientStubImpl() {
380 dbus::ObjectPath dev0("/fake/hci0/dev0");
381
382 Properties* properties = new Properties(base::Bind(
383 &ExperimentalBluetoothDeviceClientStubImpl::OnPropertyChanged,
384 base::Unretained(this),
385 dev0));
386 properties->address.ReplaceValue("00:11:22:33:44:55");
387 properties->name.ReplaceValue("Fake Device");
388 properties->paired.ReplaceValue(true);
389 properties->trusted.ReplaceValue(true);
390
391 properties_map_[dev0] = properties;
392 }
393
394 virtual ~ExperimentalBluetoothDeviceClientStubImpl() {
395 // Clean up Properties structures
396 STLDeleteValues(&properties_map_);
397 }
398
399 // ExperimentalBluetoothDeviceClient override.
400 virtual void AddObserver(Observer* observer) OVERRIDE {
401 observers_.AddObserver(observer);
402 }
403
404 // ExperimentalBluetoothDeviceClient override.
405 virtual void RemoveObserver(Observer* observer) OVERRIDE {
406 observers_.RemoveObserver(observer);
407 }
408
409 virtual std::vector<dbus::ObjectPath> GetDevicesForAdapter(
410 const dbus::ObjectPath& adapter_path) OVERRIDE {
411 std::vector<dbus::ObjectPath> object_paths;
412 if (adapter_path.value() == "/fake/hci0")
413 object_paths.push_back(dbus::ObjectPath("/fake/hci0/dev0"));
414 return object_paths;
415 }
416
417 // ExperimentalBluetoothDeviceClient override.
418 virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
419 OVERRIDE {
420 VLOG(1) << "GetProperties: " << object_path.value();
421 PropertiesMap::iterator iter = properties_map_.find(object_path);
422 if (iter != properties_map_.end())
423 return iter->second;
424 return NULL;
425 }
426
427 // ExperimentalBluetoothDeviceClient override.
428 virtual void Connect(const dbus::ObjectPath& object_path,
429 const base::Closure& callback,
430 const ErrorCallback& error_callback) OVERRIDE {
431 VLOG(1) << "Connect: " << object_path.value();
432 error_callback.Run(kNoResponseError, "");
433 }
434
435 // ExperimentalBluetoothDeviceClient override.
436 virtual void Disconnect(const dbus::ObjectPath& object_path,
437 const base::Closure& callback,
438 const ErrorCallback& error_callback) OVERRIDE {
439 VLOG(1) << "Disconnect: " << object_path.value();
440 error_callback.Run(kNoResponseError, "");
441 }
442
443 // ExperimentalBluetoothDeviceClient override.
444 virtual void ConnectProfile(const dbus::ObjectPath& object_path,
445 const std::string& uuid,
446 const base::Closure& callback,
447 const ErrorCallback& error_callback)
448 OVERRIDE {
449 VLOG(1) << "ConnectProfile: " << object_path.value() << " " << uuid;
450 error_callback.Run(kNoResponseError, "");
451 }
452
453 // ExperimentalBluetoothDeviceClient override.
454 virtual void DisconnectProfile(const dbus::ObjectPath& object_path,
455 const std::string& uuid,
456 const base::Closure& callback,
457 const ErrorCallback& error_callback)
458 OVERRIDE {
459 VLOG(1) << "DisconnectProfile: " << object_path.value() << " " << uuid;
460 error_callback.Run(kNoResponseError, "");
461 }
462
463 // ExperimentalBluetoothDeviceClient override.
464 virtual void Pair(const dbus::ObjectPath& object_path,
465 const base::Closure& callback,
466 const ErrorCallback& error_callback) OVERRIDE {
467 VLOG(1) << "Pair: " << object_path.value();
468 error_callback.Run(kNoResponseError, "");
469 }
470
471 // ExperimentalBluetoothDeviceClient override.
472 virtual void CancelPairing(const dbus::ObjectPath& object_path,
473 const base::Closure& callback,
474 const ErrorCallback& error_callback)
475 OVERRIDE {
476 VLOG(1) << "CancelPairing: " << object_path.value();
477 error_callback.Run(kNoResponseError, "");
478 }
479
480 private:
481 void OnPropertyChanged(dbus::ObjectPath object_path,
482 const std::string& property_name) {
483 FOR_EACH_OBSERVER(ExperimentalBluetoothDeviceClient::Observer, observers_,
484 DevicePropertyChanged(object_path, property_name));
485 }
486
487 // List of observers interested in event notifications from us.
488 ObserverList<Observer> observers_;
489
490 // Static properties we typedef.
491 typedef std::map<const dbus::ObjectPath, Properties *> PropertiesMap;
492 PropertiesMap properties_map_;
493 };
494
495 ExperimentalBluetoothDeviceClient::ExperimentalBluetoothDeviceClient() {
496 }
497
498 ExperimentalBluetoothDeviceClient::~ExperimentalBluetoothDeviceClient() {
499 }
500
501 ExperimentalBluetoothDeviceClient* ExperimentalBluetoothDeviceClient::Create(
502 DBusClientImplementationType type,
503 dbus::Bus* bus) {
504 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION)
505 return new ExperimentalBluetoothDeviceClientImpl(bus);
506 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type);
507 return new ExperimentalBluetoothDeviceClientStubImpl();
508 }
509
510 } // namespace chromeos
OLDNEW
« no previous file with comments | « chromeos/dbus/experimental_bluetooth_device_client.h ('k') | chromeos/dbus/experimental_bluetooth_profile_manager_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698