1 // Copyright 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.
5 #include "chromeos/dbus/bluetooth_device_client.h"
8 #include "base/logging.h"
9 #include "base/stl_util.h"
11 #include "dbus/message.h"
12 #include "dbus/object_manager.h"
13 #include "dbus/object_path.h"
14 #include "dbus/object_proxy.h"
15 #include "third_party/cros_system_api/dbus/service_constants.h"
19 const char BluetoothDeviceClient::kNoResponseError
[] =
20 "org.chromium.Error.NoResponse";
21 const char BluetoothDeviceClient::kUnknownDeviceError
[] =
22 "org.chromium.Error.UnknownDevice";
24 BluetoothDeviceClient::Properties::Properties(
25 dbus::ObjectProxy
* object_proxy
,
26 const std::string
& interface_name
,
27 const PropertyChangedCallback
& callback
)
28 : dbus::PropertySet(object_proxy
, interface_name
, callback
) {
29 RegisterProperty(bluetooth_device::kAddressProperty
, &address
);
30 RegisterProperty(bluetooth_device::kNameProperty
, &name
);
31 RegisterProperty(bluetooth_device::kIconProperty
, &icon
);
32 RegisterProperty(bluetooth_device::kClassProperty
, &bluetooth_class
);
33 RegisterProperty(bluetooth_device::kAppearanceProperty
, &appearance
);
34 RegisterProperty(bluetooth_device::kUUIDsProperty
, &uuids
);
35 RegisterProperty(bluetooth_device::kPairedProperty
, &paired
);
36 RegisterProperty(bluetooth_device::kConnectedProperty
, &connected
);
37 RegisterProperty(bluetooth_device::kTrustedProperty
, &trusted
);
38 RegisterProperty(bluetooth_device::kBlockedProperty
, &blocked
);
39 RegisterProperty(bluetooth_device::kAliasProperty
, &alias
);
40 RegisterProperty(bluetooth_device::kAdapterProperty
, &adapter
);
41 RegisterProperty(bluetooth_device::kLegacyPairingProperty
, &legacy_pairing
);
42 RegisterProperty(bluetooth_device::kModaliasProperty
, &modalias
);
43 RegisterProperty(bluetooth_device::kRSSIProperty
, &rssi
);
44 RegisterProperty(bluetooth_device::kConnectionRSSI
, &connection_rssi
);
45 RegisterProperty(bluetooth_device::kConnectionTXPower
, &connection_tx_power
);
46 RegisterProperty(bluetooth_device::kConnectionTXPowerMax
,
47 &connection_tx_power_max
);
50 BluetoothDeviceClient::Properties::~Properties() {
54 // The BluetoothDeviceClient implementation used in production.
55 class BluetoothDeviceClientImpl
56 : public BluetoothDeviceClient
,
57 public dbus::ObjectManager::Interface
{
59 BluetoothDeviceClientImpl() : weak_ptr_factory_(this) {}
61 virtual ~BluetoothDeviceClientImpl() {
62 object_manager_
->UnregisterInterface(
63 bluetooth_device::kBluetoothDeviceInterface
);
66 // BluetoothDeviceClient override.
67 virtual void AddObserver(BluetoothDeviceClient::Observer
* observer
)
70 observers_
.AddObserver(observer
);
73 // BluetoothDeviceClient override.
74 virtual void RemoveObserver(BluetoothDeviceClient::Observer
* observer
)
77 observers_
.RemoveObserver(observer
);
80 // dbus::ObjectManager::Interface override.
81 virtual dbus::PropertySet
* CreateProperties(
82 dbus::ObjectProxy
* object_proxy
,
83 const dbus::ObjectPath
& object_path
,
84 const std::string
& interface_name
) OVERRIDE
{
85 Properties
* properties
= new Properties(
88 base::Bind(&BluetoothDeviceClientImpl::OnPropertyChanged
,
89 weak_ptr_factory_
.GetWeakPtr(),
91 return static_cast<dbus::PropertySet
*>(properties
);
94 // BluetoothDeviceClient override.
95 virtual std::vector
<dbus::ObjectPath
> GetDevicesForAdapter(
96 const dbus::ObjectPath
& adapter_path
) OVERRIDE
{
97 std::vector
<dbus::ObjectPath
> object_paths
, device_paths
;
98 device_paths
= object_manager_
->GetObjectsWithInterface(
99 bluetooth_device::kBluetoothDeviceInterface
);
100 for (std::vector
<dbus::ObjectPath
>::iterator iter
= device_paths
.begin();
101 iter
!= device_paths
.end(); ++iter
) {
102 Properties
* properties
= GetProperties(*iter
);
103 if (properties
->adapter
.value() == adapter_path
)
104 object_paths
.push_back(*iter
);
109 // BluetoothDeviceClient override.
110 virtual Properties
* GetProperties(const dbus::ObjectPath
& object_path
)
112 return static_cast<Properties
*>(
113 object_manager_
->GetProperties(
115 bluetooth_device::kBluetoothDeviceInterface
));
118 // BluetoothDeviceClient override.
119 virtual void Connect(const dbus::ObjectPath
& object_path
,
120 const base::Closure
& callback
,
121 const ErrorCallback
& error_callback
) OVERRIDE
{
122 dbus::MethodCall
method_call(
123 bluetooth_device::kBluetoothDeviceInterface
,
124 bluetooth_device::kConnect
);
126 dbus::ObjectProxy
* object_proxy
=
127 object_manager_
->GetObjectProxy(object_path
);
129 error_callback
.Run(kUnknownDeviceError
, "");
133 // Connect may take an arbitrary length of time, so use no timeout.
134 object_proxy
->CallMethodWithErrorCallback(
136 dbus::ObjectProxy::TIMEOUT_INFINITE
,
137 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
138 weak_ptr_factory_
.GetWeakPtr(), callback
),
139 base::Bind(&BluetoothDeviceClientImpl::OnError
,
140 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
143 // BluetoothDeviceClient override.
144 virtual void Disconnect(const dbus::ObjectPath
& object_path
,
145 const base::Closure
& callback
,
146 const ErrorCallback
& error_callback
) OVERRIDE
{
147 dbus::MethodCall
method_call(
148 bluetooth_device::kBluetoothDeviceInterface
,
149 bluetooth_device::kDisconnect
);
151 dbus::ObjectProxy
* object_proxy
=
152 object_manager_
->GetObjectProxy(object_path
);
154 error_callback
.Run(kUnknownDeviceError
, "");
158 object_proxy
->CallMethodWithErrorCallback(
160 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
161 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
162 weak_ptr_factory_
.GetWeakPtr(), callback
),
163 base::Bind(&BluetoothDeviceClientImpl::OnError
,
164 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
167 // BluetoothDeviceClient override.
168 virtual void ConnectProfile(const dbus::ObjectPath
& object_path
,
169 const std::string
& uuid
,
170 const base::Closure
& callback
,
171 const ErrorCallback
& error_callback
) OVERRIDE
{
172 dbus::MethodCall
method_call(
173 bluetooth_device::kBluetoothDeviceInterface
,
174 bluetooth_device::kConnectProfile
);
176 dbus::MessageWriter
writer(&method_call
);
177 writer
.AppendString(uuid
);
179 dbus::ObjectProxy
* object_proxy
=
180 object_manager_
->GetObjectProxy(object_path
);
182 error_callback
.Run(kUnknownDeviceError
, "");
186 // Connect may take an arbitrary length of time, so use no timeout.
187 object_proxy
->CallMethodWithErrorCallback(
189 dbus::ObjectProxy::TIMEOUT_INFINITE
,
190 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
191 weak_ptr_factory_
.GetWeakPtr(), callback
),
192 base::Bind(&BluetoothDeviceClientImpl::OnError
,
193 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
196 // BluetoothDeviceClient override.
197 virtual void DisconnectProfile(const dbus::ObjectPath
& object_path
,
198 const std::string
& uuid
,
199 const base::Closure
& callback
,
200 const ErrorCallback
& error_callback
)
202 dbus::MethodCall
method_call(
203 bluetooth_device::kBluetoothDeviceInterface
,
204 bluetooth_device::kDisconnectProfile
);
206 dbus::MessageWriter
writer(&method_call
);
207 writer
.AppendString(uuid
);
209 dbus::ObjectProxy
* object_proxy
=
210 object_manager_
->GetObjectProxy(object_path
);
212 error_callback
.Run(kUnknownDeviceError
, "");
216 object_proxy
->CallMethodWithErrorCallback(
218 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
219 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
220 weak_ptr_factory_
.GetWeakPtr(), callback
),
221 base::Bind(&BluetoothDeviceClientImpl::OnError
,
222 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
225 // BluetoothDeviceClient override.
226 virtual void Pair(const dbus::ObjectPath
& object_path
,
227 const base::Closure
& callback
,
228 const ErrorCallback
& error_callback
) OVERRIDE
{
229 dbus::MethodCall
method_call(
230 bluetooth_device::kBluetoothDeviceInterface
,
231 bluetooth_device::kPair
);
233 dbus::ObjectProxy
* object_proxy
=
234 object_manager_
->GetObjectProxy(object_path
);
236 error_callback
.Run(kUnknownDeviceError
, "");
240 // Pairing may take an arbitrary length of time, so use no timeout.
241 object_proxy
->CallMethodWithErrorCallback(
243 dbus::ObjectProxy::TIMEOUT_INFINITE
,
244 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
245 weak_ptr_factory_
.GetWeakPtr(), callback
),
246 base::Bind(&BluetoothDeviceClientImpl::OnError
,
247 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
250 // BluetoothDeviceClient override.
251 virtual void CancelPairing(const dbus::ObjectPath
& object_path
,
252 const base::Closure
& callback
,
253 const ErrorCallback
& error_callback
)
255 dbus::MethodCall
method_call(
256 bluetooth_device::kBluetoothDeviceInterface
,
257 bluetooth_device::kCancelPairing
);
259 dbus::ObjectProxy
* object_proxy
=
260 object_manager_
->GetObjectProxy(object_path
);
262 error_callback
.Run(kUnknownDeviceError
, "");
265 object_proxy
->CallMethodWithErrorCallback(
267 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
268 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
269 weak_ptr_factory_
.GetWeakPtr(), callback
),
270 base::Bind(&BluetoothDeviceClientImpl::OnError
,
271 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
274 // BluetoothDeviceClient override.
275 virtual void StartConnectionMonitor(
276 const dbus::ObjectPath
& object_path
,
277 const base::Closure
& callback
,
278 const ErrorCallback
& error_callback
) OVERRIDE
{
279 dbus::MethodCall
method_call(bluetooth_device::kBluetoothDeviceInterface
,
280 bluetooth_device::kStartConnectionMonitor
);
282 dbus::ObjectProxy
* object_proxy
=
283 object_manager_
->GetObjectProxy(object_path
);
285 error_callback
.Run(kUnknownDeviceError
, "");
288 object_proxy
->CallMethodWithErrorCallback(
290 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
291 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
292 weak_ptr_factory_
.GetWeakPtr(),
294 base::Bind(&BluetoothDeviceClientImpl::OnError
,
295 weak_ptr_factory_
.GetWeakPtr(),
299 // BluetoothDeviceClient override.
300 virtual void StopConnectionMonitor(
301 const dbus::ObjectPath
& object_path
,
302 const base::Closure
& callback
,
303 const ErrorCallback
& error_callback
) OVERRIDE
{
304 dbus::MethodCall
method_call(bluetooth_device::kBluetoothDeviceInterface
,
305 bluetooth_device::kStopConnectionMonitor
);
307 dbus::ObjectProxy
* object_proxy
=
308 object_manager_
->GetObjectProxy(object_path
);
310 error_callback
.Run(kUnknownDeviceError
, "");
313 object_proxy
->CallMethodWithErrorCallback(
315 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
316 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
317 weak_ptr_factory_
.GetWeakPtr(),
319 base::Bind(&BluetoothDeviceClientImpl::OnError
,
320 weak_ptr_factory_
.GetWeakPtr(),
325 virtual void Init(dbus::Bus
* bus
) OVERRIDE
{
326 object_manager_
= bus
->GetObjectManager(
327 bluetooth_object_manager::kBluetoothObjectManagerServiceName
,
329 bluetooth_object_manager::kBluetoothObjectManagerServicePath
));
330 object_manager_
->RegisterInterface(
331 bluetooth_device::kBluetoothDeviceInterface
, this);
335 // Called by dbus::ObjectManager when an object with the device interface
336 // is created. Informs observers.
337 virtual void ObjectAdded(const dbus::ObjectPath
& object_path
,
338 const std::string
& interface_name
) OVERRIDE
{
339 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
340 DeviceAdded(object_path
));
343 // Called by dbus::ObjectManager when an object with the device interface
344 // is removed. Informs observers.
345 virtual void ObjectRemoved(const dbus::ObjectPath
& object_path
,
346 const std::string
& interface_name
) OVERRIDE
{
347 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
348 DeviceRemoved(object_path
));
351 // Called by BluetoothPropertySet when a property value is changed,
352 // either by result of a signal or response to a GetAll() or Get()
353 // call. Informs observers.
354 void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
355 const std::string
& property_name
) {
356 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
357 DevicePropertyChanged(object_path
, property_name
));
360 // Called when a response for successful method call is received.
361 void OnSuccess(const base::Closure
& callback
,
362 dbus::Response
* response
) {
367 // Called when a response for a failed method call is received.
368 void OnError(const ErrorCallback
& error_callback
,
369 dbus::ErrorResponse
* response
) {
370 // Error response has optional error message argument.
371 std::string error_name
;
372 std::string error_message
;
374 dbus::MessageReader
reader(response
);
375 error_name
= response
->GetErrorName();
376 reader
.PopString(&error_message
);
378 error_name
= kNoResponseError
;
381 error_callback
.Run(error_name
, error_message
);
384 dbus::ObjectManager
* object_manager_
;
386 // List of observers interested in event notifications from us.
387 ObserverList
<BluetoothDeviceClient::Observer
> observers_
;
389 // Weak pointer factory for generating 'this' pointers that might live longer
391 // Note: This should remain the last member so it'll be destroyed and
392 // invalidate its weak pointers before any other members are destroyed.
393 base::WeakPtrFactory
<BluetoothDeviceClientImpl
> weak_ptr_factory_
;
395 DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl
);
398 BluetoothDeviceClient::BluetoothDeviceClient() {
401 BluetoothDeviceClient::~BluetoothDeviceClient() {
404 BluetoothDeviceClient
* BluetoothDeviceClient::Create() {
405 return new BluetoothDeviceClientImpl();
408 } // namespace chromeos