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_proxy.h"
14 #include "third_party/cros_system_api/dbus/service_constants.h"
20 // Value returned for the the RSSI or TX power if it cannot be read.
21 const int kUnknownPower
= 127;
25 const char BluetoothDeviceClient::kNoResponseError
[] =
26 "org.chromium.Error.NoResponse";
27 const char BluetoothDeviceClient::kUnknownDeviceError
[] =
28 "org.chromium.Error.UnknownDevice";
30 BluetoothDeviceClient::Properties::Properties(
31 dbus::ObjectProxy
* object_proxy
,
32 const std::string
& interface_name
,
33 const PropertyChangedCallback
& callback
)
34 : dbus::PropertySet(object_proxy
, interface_name
, callback
) {
35 RegisterProperty(bluetooth_device::kAddressProperty
, &address
);
36 RegisterProperty(bluetooth_device::kNameProperty
, &name
);
37 RegisterProperty(bluetooth_device::kIconProperty
, &icon
);
38 RegisterProperty(bluetooth_device::kClassProperty
, &bluetooth_class
);
39 RegisterProperty(bluetooth_device::kAppearanceProperty
, &appearance
);
40 RegisterProperty(bluetooth_device::kUUIDsProperty
, &uuids
);
41 RegisterProperty(bluetooth_device::kPairedProperty
, &paired
);
42 RegisterProperty(bluetooth_device::kConnectedProperty
, &connected
);
43 RegisterProperty(bluetooth_device::kTrustedProperty
, &trusted
);
44 RegisterProperty(bluetooth_device::kBlockedProperty
, &blocked
);
45 RegisterProperty(bluetooth_device::kAliasProperty
, &alias
);
46 RegisterProperty(bluetooth_device::kAdapterProperty
, &adapter
);
47 RegisterProperty(bluetooth_device::kLegacyPairingProperty
, &legacy_pairing
);
48 RegisterProperty(bluetooth_device::kModaliasProperty
, &modalias
);
49 RegisterProperty(bluetooth_device::kRSSIProperty
, &rssi
);
50 RegisterProperty(bluetooth_device::kTxPowerProperty
, &tx_power
);
53 BluetoothDeviceClient::Properties::~Properties() {
57 // The BluetoothDeviceClient implementation used in production.
58 class BluetoothDeviceClientImpl
59 : public BluetoothDeviceClient
,
60 public dbus::ObjectManager::Interface
{
62 BluetoothDeviceClientImpl()
63 : object_manager_(NULL
), weak_ptr_factory_(this) {}
65 ~BluetoothDeviceClientImpl() override
{
66 object_manager_
->UnregisterInterface(
67 bluetooth_device::kBluetoothDeviceInterface
);
70 // BluetoothDeviceClient override.
71 void AddObserver(BluetoothDeviceClient::Observer
* observer
) override
{
73 observers_
.AddObserver(observer
);
76 // BluetoothDeviceClient override.
77 void RemoveObserver(BluetoothDeviceClient::Observer
* observer
) override
{
79 observers_
.RemoveObserver(observer
);
82 // dbus::ObjectManager::Interface override.
83 dbus::PropertySet
* CreateProperties(
84 dbus::ObjectProxy
* object_proxy
,
85 const dbus::ObjectPath
& object_path
,
86 const std::string
& interface_name
) override
{
87 Properties
* properties
= new Properties(
90 base::Bind(&BluetoothDeviceClientImpl::OnPropertyChanged
,
91 weak_ptr_factory_
.GetWeakPtr(),
93 return static_cast<dbus::PropertySet
*>(properties
);
96 // BluetoothDeviceClient override.
97 std::vector
<dbus::ObjectPath
> GetDevicesForAdapter(
98 const dbus::ObjectPath
& adapter_path
) override
{
99 std::vector
<dbus::ObjectPath
> object_paths
, device_paths
;
100 device_paths
= object_manager_
->GetObjectsWithInterface(
101 bluetooth_device::kBluetoothDeviceInterface
);
102 for (std::vector
<dbus::ObjectPath
>::iterator iter
= device_paths
.begin();
103 iter
!= device_paths
.end(); ++iter
) {
104 Properties
* properties
= GetProperties(*iter
);
105 if (properties
->adapter
.value() == adapter_path
)
106 object_paths
.push_back(*iter
);
111 // BluetoothDeviceClient override.
112 Properties
* GetProperties(const dbus::ObjectPath
& object_path
) override
{
113 return static_cast<Properties
*>(
114 object_manager_
->GetProperties(
116 bluetooth_device::kBluetoothDeviceInterface
));
119 // BluetoothDeviceClient override.
120 void Connect(const dbus::ObjectPath
& object_path
,
121 const base::Closure
& callback
,
122 const ErrorCallback
& error_callback
) override
{
123 dbus::MethodCall
method_call(
124 bluetooth_device::kBluetoothDeviceInterface
,
125 bluetooth_device::kConnect
);
127 dbus::ObjectProxy
* object_proxy
=
128 object_manager_
->GetObjectProxy(object_path
);
130 error_callback
.Run(kUnknownDeviceError
, "");
134 // Connect may take an arbitrary length of time, so use no timeout.
135 object_proxy
->CallMethodWithErrorCallback(
137 dbus::ObjectProxy::TIMEOUT_INFINITE
,
138 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
139 weak_ptr_factory_
.GetWeakPtr(), callback
),
140 base::Bind(&BluetoothDeviceClientImpl::OnError
,
141 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
144 // BluetoothDeviceClient override.
145 void Disconnect(const dbus::ObjectPath
& object_path
,
146 const base::Closure
& callback
,
147 const ErrorCallback
& error_callback
) override
{
148 dbus::MethodCall
method_call(
149 bluetooth_device::kBluetoothDeviceInterface
,
150 bluetooth_device::kDisconnect
);
152 dbus::ObjectProxy
* object_proxy
=
153 object_manager_
->GetObjectProxy(object_path
);
155 error_callback
.Run(kUnknownDeviceError
, "");
159 object_proxy
->CallMethodWithErrorCallback(
161 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
162 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
163 weak_ptr_factory_
.GetWeakPtr(), callback
),
164 base::Bind(&BluetoothDeviceClientImpl::OnError
,
165 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
168 // BluetoothDeviceClient override.
169 void ConnectProfile(const dbus::ObjectPath
& object_path
,
170 const std::string
& uuid
,
171 const base::Closure
& callback
,
172 const ErrorCallback
& error_callback
) override
{
173 dbus::MethodCall
method_call(
174 bluetooth_device::kBluetoothDeviceInterface
,
175 bluetooth_device::kConnectProfile
);
177 dbus::MessageWriter
writer(&method_call
);
178 writer
.AppendString(uuid
);
180 dbus::ObjectProxy
* object_proxy
=
181 object_manager_
->GetObjectProxy(object_path
);
183 error_callback
.Run(kUnknownDeviceError
, "");
187 // Connect may take an arbitrary length of time, so use no timeout.
188 object_proxy
->CallMethodWithErrorCallback(
190 dbus::ObjectProxy::TIMEOUT_INFINITE
,
191 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
192 weak_ptr_factory_
.GetWeakPtr(), callback
),
193 base::Bind(&BluetoothDeviceClientImpl::OnError
,
194 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
197 // BluetoothDeviceClient override.
198 void DisconnectProfile(const dbus::ObjectPath
& object_path
,
199 const std::string
& uuid
,
200 const base::Closure
& callback
,
201 const ErrorCallback
& error_callback
) override
{
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 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 void CancelPairing(const dbus::ObjectPath
& object_path
,
252 const base::Closure
& callback
,
253 const ErrorCallback
& error_callback
) override
{
254 dbus::MethodCall
method_call(
255 bluetooth_device::kBluetoothDeviceInterface
,
256 bluetooth_device::kCancelPairing
);
258 dbus::ObjectProxy
* object_proxy
=
259 object_manager_
->GetObjectProxy(object_path
);
261 error_callback
.Run(kUnknownDeviceError
, "");
264 object_proxy
->CallMethodWithErrorCallback(
266 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
267 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
268 weak_ptr_factory_
.GetWeakPtr(), callback
),
269 base::Bind(&BluetoothDeviceClientImpl::OnError
,
270 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
273 // BluetoothDeviceClient override.
274 void GetConnInfo(const dbus::ObjectPath
& object_path
,
275 const ConnInfoCallback
& callback
,
276 const ErrorCallback
& error_callback
) override
{
277 dbus::MethodCall
method_call(
278 bluetooth_plugin_device::kBluetoothPluginInterface
,
279 bluetooth_plugin_device::kGetConnInfo
);
281 dbus::ObjectProxy
* object_proxy
=
282 object_manager_
->GetObjectProxy(object_path
);
284 error_callback
.Run(kUnknownDeviceError
, "");
287 object_proxy
->CallMethodWithErrorCallback(
288 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
289 base::Bind(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess
,
290 weak_ptr_factory_
.GetWeakPtr(), callback
),
291 base::Bind(&BluetoothDeviceClientImpl::OnError
,
292 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
296 void Init(dbus::Bus
* bus
) override
{
297 object_manager_
= bus
->GetObjectManager(
298 bluetooth_object_manager::kBluetoothObjectManagerServiceName
,
300 bluetooth_object_manager::kBluetoothObjectManagerServicePath
));
301 object_manager_
->RegisterInterface(
302 bluetooth_device::kBluetoothDeviceInterface
, this);
306 // Called by dbus::ObjectManager when an object with the device interface
307 // is created. Informs observers.
308 void ObjectAdded(const dbus::ObjectPath
& object_path
,
309 const std::string
& interface_name
) override
{
310 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
311 DeviceAdded(object_path
));
314 // Called by dbus::ObjectManager when an object with the device interface
315 // is removed. Informs observers.
316 void ObjectRemoved(const dbus::ObjectPath
& object_path
,
317 const std::string
& interface_name
) override
{
318 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
319 DeviceRemoved(object_path
));
322 // Called by BluetoothPropertySet when a property value is changed,
323 // either by result of a signal or response to a GetAll() or Get()
324 // call. Informs observers.
325 void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
326 const std::string
& property_name
) {
327 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
328 DevicePropertyChanged(object_path
, property_name
));
331 // Called when a response for successful method call is received.
332 void OnSuccess(const base::Closure
& callback
,
333 dbus::Response
* response
) {
338 // Called when a response for the GetConnInfo method is received.
339 void OnGetConnInfoSuccess(const ConnInfoCallback
& callback
,
340 dbus::Response
* response
) {
341 int16 rssi
= kUnknownPower
;
342 int16 transmit_power
= kUnknownPower
;
343 int16 max_transmit_power
= kUnknownPower
;
346 LOG(ERROR
) << "GetConnInfo succeeded, but no response received.";
347 callback
.Run(rssi
, transmit_power
, max_transmit_power
);
351 dbus::MessageReader
reader(response
);
352 if (!reader
.PopInt16(&rssi
) || !reader
.PopInt16(&transmit_power
) ||
353 !reader
.PopInt16(&max_transmit_power
)) {
354 LOG(ERROR
) << "Arguments for GetConnInfo invalid.";
356 callback
.Run(rssi
, transmit_power
, max_transmit_power
);
359 // Called when a response for a failed method call is received.
360 void OnError(const ErrorCallback
& error_callback
,
361 dbus::ErrorResponse
* response
) {
362 // Error response has optional error message argument.
363 std::string error_name
;
364 std::string error_message
;
366 dbus::MessageReader
reader(response
);
367 error_name
= response
->GetErrorName();
368 reader
.PopString(&error_message
);
370 error_name
= kNoResponseError
;
373 error_callback
.Run(error_name
, error_message
);
376 dbus::ObjectManager
* object_manager_
;
378 // List of observers interested in event notifications from us.
379 base::ObserverList
<BluetoothDeviceClient::Observer
> observers_
;
381 // Weak pointer factory for generating 'this' pointers that might live longer
383 // Note: This should remain the last member so it'll be destroyed and
384 // invalidate its weak pointers before any other members are destroyed.
385 base::WeakPtrFactory
<BluetoothDeviceClientImpl
> weak_ptr_factory_
;
387 DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl
);
390 BluetoothDeviceClient::BluetoothDeviceClient() {
393 BluetoothDeviceClient::~BluetoothDeviceClient() {
396 BluetoothDeviceClient
* BluetoothDeviceClient::Create() {
397 return new BluetoothDeviceClientImpl();
400 } // namespace chromeos