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()
60 : object_manager_(NULL
), weak_ptr_factory_(this) {}
62 virtual ~BluetoothDeviceClientImpl() {
63 object_manager_
->UnregisterInterface(
64 bluetooth_device::kBluetoothDeviceInterface
);
67 // BluetoothDeviceClient override.
68 virtual void AddObserver(BluetoothDeviceClient::Observer
* observer
)
71 observers_
.AddObserver(observer
);
74 // BluetoothDeviceClient override.
75 virtual void RemoveObserver(BluetoothDeviceClient::Observer
* observer
)
78 observers_
.RemoveObserver(observer
);
81 // dbus::ObjectManager::Interface override.
82 virtual 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 virtual 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 virtual Properties
* GetProperties(const dbus::ObjectPath
& object_path
)
113 return static_cast<Properties
*>(
114 object_manager_
->GetProperties(
116 bluetooth_device::kBluetoothDeviceInterface
));
119 // BluetoothDeviceClient override.
120 virtual 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 virtual 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 virtual 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 virtual void DisconnectProfile(const dbus::ObjectPath
& object_path
,
199 const std::string
& uuid
,
200 const base::Closure
& callback
,
201 const ErrorCallback
& error_callback
)
203 dbus::MethodCall
method_call(
204 bluetooth_device::kBluetoothDeviceInterface
,
205 bluetooth_device::kDisconnectProfile
);
207 dbus::MessageWriter
writer(&method_call
);
208 writer
.AppendString(uuid
);
210 dbus::ObjectProxy
* object_proxy
=
211 object_manager_
->GetObjectProxy(object_path
);
213 error_callback
.Run(kUnknownDeviceError
, "");
217 object_proxy
->CallMethodWithErrorCallback(
219 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
220 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
221 weak_ptr_factory_
.GetWeakPtr(), callback
),
222 base::Bind(&BluetoothDeviceClientImpl::OnError
,
223 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
226 // BluetoothDeviceClient override.
227 virtual void Pair(const dbus::ObjectPath
& object_path
,
228 const base::Closure
& callback
,
229 const ErrorCallback
& error_callback
) override
{
230 dbus::MethodCall
method_call(
231 bluetooth_device::kBluetoothDeviceInterface
,
232 bluetooth_device::kPair
);
234 dbus::ObjectProxy
* object_proxy
=
235 object_manager_
->GetObjectProxy(object_path
);
237 error_callback
.Run(kUnknownDeviceError
, "");
241 // Pairing may take an arbitrary length of time, so use no timeout.
242 object_proxy
->CallMethodWithErrorCallback(
244 dbus::ObjectProxy::TIMEOUT_INFINITE
,
245 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
246 weak_ptr_factory_
.GetWeakPtr(), callback
),
247 base::Bind(&BluetoothDeviceClientImpl::OnError
,
248 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
251 // BluetoothDeviceClient override.
252 virtual void CancelPairing(const dbus::ObjectPath
& object_path
,
253 const base::Closure
& callback
,
254 const ErrorCallback
& error_callback
)
256 dbus::MethodCall
method_call(
257 bluetooth_device::kBluetoothDeviceInterface
,
258 bluetooth_device::kCancelPairing
);
260 dbus::ObjectProxy
* object_proxy
=
261 object_manager_
->GetObjectProxy(object_path
);
263 error_callback
.Run(kUnknownDeviceError
, "");
266 object_proxy
->CallMethodWithErrorCallback(
268 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
269 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
270 weak_ptr_factory_
.GetWeakPtr(), callback
),
271 base::Bind(&BluetoothDeviceClientImpl::OnError
,
272 weak_ptr_factory_
.GetWeakPtr(), error_callback
));
275 // BluetoothDeviceClient override.
276 virtual void StartConnectionMonitor(
277 const dbus::ObjectPath
& object_path
,
278 const base::Closure
& callback
,
279 const ErrorCallback
& error_callback
) override
{
280 dbus::MethodCall
method_call(bluetooth_device::kBluetoothDeviceInterface
,
281 bluetooth_device::kStartConnectionMonitor
);
283 dbus::ObjectProxy
* object_proxy
=
284 object_manager_
->GetObjectProxy(object_path
);
286 error_callback
.Run(kUnknownDeviceError
, "");
289 object_proxy
->CallMethodWithErrorCallback(
291 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
292 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
293 weak_ptr_factory_
.GetWeakPtr(),
295 base::Bind(&BluetoothDeviceClientImpl::OnError
,
296 weak_ptr_factory_
.GetWeakPtr(),
300 // BluetoothDeviceClient override.
301 virtual void StopConnectionMonitor(
302 const dbus::ObjectPath
& object_path
,
303 const base::Closure
& callback
,
304 const ErrorCallback
& error_callback
) override
{
305 dbus::MethodCall
method_call(bluetooth_device::kBluetoothDeviceInterface
,
306 bluetooth_device::kStopConnectionMonitor
);
308 dbus::ObjectProxy
* object_proxy
=
309 object_manager_
->GetObjectProxy(object_path
);
311 error_callback
.Run(kUnknownDeviceError
, "");
314 object_proxy
->CallMethodWithErrorCallback(
316 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT
,
317 base::Bind(&BluetoothDeviceClientImpl::OnSuccess
,
318 weak_ptr_factory_
.GetWeakPtr(),
320 base::Bind(&BluetoothDeviceClientImpl::OnError
,
321 weak_ptr_factory_
.GetWeakPtr(),
326 virtual void Init(dbus::Bus
* bus
) override
{
327 object_manager_
= bus
->GetObjectManager(
328 bluetooth_object_manager::kBluetoothObjectManagerServiceName
,
330 bluetooth_object_manager::kBluetoothObjectManagerServicePath
));
331 object_manager_
->RegisterInterface(
332 bluetooth_device::kBluetoothDeviceInterface
, this);
336 // Called by dbus::ObjectManager when an object with the device interface
337 // is created. Informs observers.
338 virtual void ObjectAdded(const dbus::ObjectPath
& object_path
,
339 const std::string
& interface_name
) override
{
340 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
341 DeviceAdded(object_path
));
344 // Called by dbus::ObjectManager when an object with the device interface
345 // is removed. Informs observers.
346 virtual void ObjectRemoved(const dbus::ObjectPath
& object_path
,
347 const std::string
& interface_name
) override
{
348 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
349 DeviceRemoved(object_path
));
352 // Called by BluetoothPropertySet when a property value is changed,
353 // either by result of a signal or response to a GetAll() or Get()
354 // call. Informs observers.
355 void OnPropertyChanged(const dbus::ObjectPath
& object_path
,
356 const std::string
& property_name
) {
357 FOR_EACH_OBSERVER(BluetoothDeviceClient::Observer
, observers_
,
358 DevicePropertyChanged(object_path
, property_name
));
361 // Called when a response for successful method call is received.
362 void OnSuccess(const base::Closure
& callback
,
363 dbus::Response
* response
) {
368 // Called when a response for a failed method call is received.
369 void OnError(const ErrorCallback
& error_callback
,
370 dbus::ErrorResponse
* response
) {
371 // Error response has optional error message argument.
372 std::string error_name
;
373 std::string error_message
;
375 dbus::MessageReader
reader(response
);
376 error_name
= response
->GetErrorName();
377 reader
.PopString(&error_message
);
379 error_name
= kNoResponseError
;
382 error_callback
.Run(error_name
, error_message
);
385 dbus::ObjectManager
* object_manager_
;
387 // List of observers interested in event notifications from us.
388 ObserverList
<BluetoothDeviceClient::Observer
> observers_
;
390 // Weak pointer factory for generating 'this' pointers that might live longer
392 // Note: This should remain the last member so it'll be destroyed and
393 // invalidate its weak pointers before any other members are destroyed.
394 base::WeakPtrFactory
<BluetoothDeviceClientImpl
> weak_ptr_factory_
;
396 DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl
);
399 BluetoothDeviceClient::BluetoothDeviceClient() {
402 BluetoothDeviceClient::~BluetoothDeviceClient() {
405 BluetoothDeviceClient
* BluetoothDeviceClient::Create() {
406 return new BluetoothDeviceClientImpl();
409 } // namespace chromeos