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