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
);
52 BluetoothDeviceClient::Properties::~Properties() {
56 // The BluetoothDeviceClient implementation used in production.
57 class BluetoothDeviceClientImpl
58 : public BluetoothDeviceClient
,
59 public dbus::ObjectManager::Interface
{
61 BluetoothDeviceClientImpl()
62 : object_manager_(NULL
), weak_ptr_factory_(this) {}
64 ~BluetoothDeviceClientImpl() override
{
65 object_manager_
->UnregisterInterface(
66 bluetooth_device::kBluetoothDeviceInterface
);
69 // BluetoothDeviceClient override.
70 void AddObserver(BluetoothDeviceClient::Observer
* observer
) override
{
72 observers_
.AddObserver(observer
);
75 // BluetoothDeviceClient override.
76 void RemoveObserver(BluetoothDeviceClient::Observer
* observer
) override
{
78 observers_
.RemoveObserver(observer
);
81 // dbus::ObjectManager::Interface override.
82 dbus::PropertySet
* CreateProperties(
83 dbus::ObjectProxy
* object_proxy
,
84 const dbus::ObjectPath
& object_path
,
85 const std::string
& interface_name
) override
{
86 Properties
* properties
= new Properties(
89 base::Bind(&BluetoothDeviceClientImpl::OnPropertyChanged
,
90 weak_ptr_factory_
.GetWeakPtr(),
92 return static_cast<dbus::PropertySet
*>(properties
);
95 // BluetoothDeviceClient override.
96 std::vector
<dbus::ObjectPath
> GetDevicesForAdapter(
97 const dbus::ObjectPath
& adapter_path
) override
{
98 std::vector
<dbus::ObjectPath
> object_paths
, device_paths
;
99 device_paths
= object_manager_
->GetObjectsWithInterface(
100 bluetooth_device::kBluetoothDeviceInterface
);
101 for (std::vector
<dbus::ObjectPath
>::iterator iter
= device_paths
.begin();
102 iter
!= device_paths
.end(); ++iter
) {
103 Properties
* properties
= GetProperties(*iter
);
104 if (properties
->adapter
.value() == adapter_path
)
105 object_paths
.push_back(*iter
);
110 // BluetoothDeviceClient override.
111 Properties
* GetProperties(const dbus::ObjectPath
& object_path
) override
{
112 return static_cast<Properties
*>(
113 object_manager_
->GetProperties(
115 bluetooth_device::kBluetoothDeviceInterface
));
118 // BluetoothDeviceClient override.
119 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 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 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 void DisconnectProfile(const dbus::ObjectPath
& object_path
,
198 const std::string
& uuid
,
199 const base::Closure
& callback
,
200 const ErrorCallback
& error_callback
) override
{
201 dbus::MethodCall
method_call(
202 bluetooth_device::kBluetoothDeviceInterface
,
203 bluetooth_device::kDisconnectProfile
);
205 dbus::MessageWriter
writer(&method_call
);
206 writer
.AppendString(uuid
);
208 dbus::ObjectProxy
* object_proxy
=
209 object_manager_
->GetObjectProxy(object_path
);
211 error_callback
.Run(kUnknownDeviceError
, "");
215 object_proxy
->CallMethodWithErrorCallback(
217 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
218 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
219 weak_ptr_factory_
.GetWeakPtr(), callback
),
220 base::Bind(&BluetoothDeviceClientImpl::OnError
,
221 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
224 // BluetoothDeviceClient override.
225 void Pair(const dbus::ObjectPath
& object_path
,
226 const base::Closure
& callback
,
227 const ErrorCallback
& error_callback
) override
{
228 dbus::MethodCall
method_call(
229 bluetooth_device::kBluetoothDeviceInterface
,
230 bluetooth_device::kPair
);
232 dbus::ObjectProxy
* object_proxy
=
233 object_manager_
->GetObjectProxy(object_path
);
235 error_callback
.Run(kUnknownDeviceError
, "");
239 // Pairing may take an arbitrary length of time, so use no timeout.
240 object_proxy
->CallMethodWithErrorCallback(
242 dbus::ObjectProxy::TIMEOUT_INFINITE
,
243 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
244 weak_ptr_factory_
.GetWeakPtr(), callback
),
245 base::Bind(&BluetoothDeviceClientImpl::OnError
,
246 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
249 // BluetoothDeviceClient override.
250 void CancelPairing(const dbus::ObjectPath
& object_path
,
251 const base::Closure
& callback
,
252 const ErrorCallback
& error_callback
) override
{
253 dbus::MethodCall
method_call(
254 bluetooth_device::kBluetoothDeviceInterface
,
255 bluetooth_device::kCancelPairing
);
257 dbus::ObjectProxy
* object_proxy
=
258 object_manager_
->GetObjectProxy(object_path
);
260 error_callback
.Run(kUnknownDeviceError
, "");
263 object_proxy
->CallMethodWithErrorCallback(
265 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
266 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
267 weak_ptr_factory_
.GetWeakPtr(), callback
),
268 base::Bind(&BluetoothDeviceClientImpl::OnError
,
269 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
272 // BluetoothDeviceClient override.
273 void GetConnInfo(const dbus::ObjectPath
& object_path
,
274 const ConnInfoCallback
& callback
,
275 const ErrorCallback
& error_callback
) override
{
276 dbus::MethodCall
method_call(
277 bluetooth_plugin_device::kBluetoothPluginInterface
,
278 bluetooth_plugin_device::kGetConnInfo
);
280 dbus::ObjectProxy
* object_proxy
=
281 object_manager_
->GetObjectProxy(object_path
);
283 error_callback
.Run(kUnknownDeviceError
, "");
286 object_proxy
->CallMethodWithErrorCallback(
287 &method_call
, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
288 base::Bind(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess
,
289 weak_ptr_factory_
.GetWeakPtr(), callback
),
290 base::Bind(&BluetoothDeviceClientImpl::OnError
,
291 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
295 void Init(dbus::Bus
* bus
) override
{
296 object_manager_
= bus
->GetObjectManager(
297 bluetooth_object_manager::kBluetoothObjectManagerServiceName
,
299 bluetooth_object_manager::kBluetoothObjectManagerServicePath
));
300 object_manager_
->RegisterInterface(
301 bluetooth_device::kBluetoothDeviceInterface
, this);
305 // Called by dbus::ObjectManager when an object with the device interface
306 // is created. Informs observers.
307 void ObjectAdded(const dbus::ObjectPath
& object_path
,
308 const std::string
& interface_name
) override
{
309 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
310 DeviceAdded(object_path
));
313 // Called by dbus::ObjectManager when an object with the device interface
314 // is removed. Informs observers.
315 void ObjectRemoved(const dbus::ObjectPath
& object_path
,
316 const std::string
& interface_name
) override
{
317 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
318 DeviceRemoved(object_path
));
321 // Called by BluetoothPropertySet when a property value is changed,
322 // either by result of a signal or response to a GetAll() or Get()
323 // call. Informs observers.
324 void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
325 const std::string
& property_name
) {
326 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
327 DevicePropertyChanged(object_path
, property_name
));
330 // Called when a response for successful method call is received.
331 void OnSuccess(const base::Closure
& callback
,
332 dbus::Response
* response
) {
337 // Called when a response for the GetConnInfo method is received.
338 void OnGetConnInfoSuccess(const ConnInfoCallback
& callback
,
339 dbus::Response
* response
) {
340 int16 rssi
= kUnknownPower
;
341 int16 transmit_power
= kUnknownPower
;
342 int16 max_transmit_power
= kUnknownPower
;
345 LOG(ERROR
) << "GetConnInfo succeeded, but no response received.";
346 callback
.Run(rssi
, transmit_power
, max_transmit_power
);
350 dbus::MessageReader
reader(response
);
351 if (!reader
.PopInt16(&rssi
) || !reader
.PopInt16(&transmit_power
) ||
352 !reader
.PopInt16(&max_transmit_power
)) {
353 LOG(ERROR
) << "Arguments for GetConnInfo invalid.";
355 callback
.Run(rssi
, transmit_power
, max_transmit_power
);
358 // Called when a response for a failed method call is received.
359 void OnError(const ErrorCallback
& error_callback
,
360 dbus::ErrorResponse
* response
) {
361 // Error response has optional error message argument.
362 std::string error_name
;
363 std::string error_message
;
365 dbus::MessageReader
reader(response
);
366 error_name
= response
->GetErrorName();
367 reader
.PopString(&error_message
);
369 error_name
= kNoResponseError
;
372 error_callback
.Run(error_name
, error_message
);
375 dbus::ObjectManager
* object_manager_
;
377 // List of observers interested in event notifications from us.
378 ObserverList
<BluetoothDeviceClient::Observer
> observers_
;
380 // Weak pointer factory for generating 'this' pointers that might live longer
382 // Note: This should remain the last member so it'll be destroyed and
383 // invalidate its weak pointers before any other members are destroyed.
384 base::WeakPtrFactory
<BluetoothDeviceClientImpl
> weak_ptr_factory_
;
386 DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl
);
389 BluetoothDeviceClient::BluetoothDeviceClient() {
392 BluetoothDeviceClient::~BluetoothDeviceClient() {
395 BluetoothDeviceClient
* BluetoothDeviceClient::Create() {
396 return new BluetoothDeviceClientImpl();
399 } // namespace chromeos