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