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. 4 5 #include "chromeos/dbus/bluetooth_device_client.h" 6 7 #include "base/bind.h" 8 #include "base/logging.h" 9 #include "base/stl_util.h" 10 #include "dbus/bus.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" 16 17 namespace chromeos { 18 19 const char BluetoothDeviceClient::kNoResponseError[] = 20 "org.chromium.Error.NoResponse"; 21 const char BluetoothDeviceClient::kUnknownDeviceError[] = 22 "org.chromium.Error.UnknownDevice"; 23 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); 48 } 49 50 BluetoothDeviceClient::Properties::~Properties() { 51 } 52 53 54 // The BluetoothDeviceClient implementation used in production. 55 class BluetoothDeviceClientImpl 56 : public BluetoothDeviceClient, 57 public dbus::ObjectManager::Interface { 58 public: 59 BluetoothDeviceClientImpl() : weak_ptr_factory_(this) {} 60 61 virtual ~BluetoothDeviceClientImpl() { 62 object_manager_->UnregisterInterface( 63 bluetooth_device::kBluetoothDeviceInterface); 64 } 65 66 // BluetoothDeviceClient override. 67 virtual void AddObserver(BluetoothDeviceClient::Observer* observer) 68 OVERRIDE { 69 DCHECK(observer); 70 observers_.AddObserver(observer); 71 } 72 73 // BluetoothDeviceClient override. 74 virtual void RemoveObserver(BluetoothDeviceClient::Observer* observer) 75 OVERRIDE { 76 DCHECK(observer); 77 observers_.RemoveObserver(observer); 78 } 79 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( 86 object_proxy, 87 interface_name, 88 base::Bind(&BluetoothDeviceClientImpl::OnPropertyChanged, 89 weak_ptr_factory_.GetWeakPtr(), 90 object_path)); 91 return static_cast<dbus::PropertySet*>(properties); 92 } 93 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); 105 } 106 return object_paths; 107 } 108 109 // BluetoothDeviceClient override. 110 virtual Properties* GetProperties(const dbus::ObjectPath& object_path) 111 OVERRIDE { 112 return static_cast<Properties*>( 113 object_manager_->GetProperties( 114 object_path, 115 bluetooth_device::kBluetoothDeviceInterface)); 116 } 117 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); 125 126 dbus::ObjectProxy* object_proxy = 127 object_manager_->GetObjectProxy(object_path); 128 if (!object_proxy) { 129 error_callback.Run(kUnknownDeviceError, ""); 130 return; 131 } 132 133 // Connect may take an arbitrary length of time, so use no timeout. 134 object_proxy->CallMethodWithErrorCallback( 135 &method_call, 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)); 141 } 142 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); 150 151 dbus::ObjectProxy* object_proxy = 152 object_manager_->GetObjectProxy(object_path); 153 if (!object_proxy) { 154 error_callback.Run(kUnknownDeviceError, ""); 155 return; 156 } 157 158 object_proxy->CallMethodWithErrorCallback( 159 &method_call, 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)); 165 } 166 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); 175 176 dbus::MessageWriter writer(&method_call); 177 writer.AppendString(uuid); 178 179 dbus::ObjectProxy* object_proxy = 180 object_manager_->GetObjectProxy(object_path); 181 if (!object_proxy) { 182 error_callback.Run(kUnknownDeviceError, ""); 183 return; 184 } 185 186 // Connect may take an arbitrary length of time, so use no timeout. 187 object_proxy->CallMethodWithErrorCallback( 188 &method_call, 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)); 194 } 195 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) 201 OVERRIDE { 202 dbus::MethodCall method_call( 203 bluetooth_device::kBluetoothDeviceInterface, 204 bluetooth_device::kDisconnectProfile); 205 206 dbus::MessageWriter writer(&method_call); 207 writer.AppendString(uuid); 208 209 dbus::ObjectProxy* object_proxy = 210 object_manager_->GetObjectProxy(object_path); 211 if (!object_proxy) { 212 error_callback.Run(kUnknownDeviceError, ""); 213 return; 214 } 215 216 object_proxy->CallMethodWithErrorCallback( 217 &method_call, 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)); 223 } 224 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); 232 233 dbus::ObjectProxy* object_proxy = 234 object_manager_->GetObjectProxy(object_path); 235 if (!object_proxy) { 236 error_callback.Run(kUnknownDeviceError, ""); 237 return; 238 } 239 240 // Pairing may take an arbitrary length of time, so use no timeout. 241 object_proxy->CallMethodWithErrorCallback( 242 &method_call, 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)); 248 } 249 250 // BluetoothDeviceClient override. 251 virtual void CancelPairing(const dbus::ObjectPath& object_path, 252 const base::Closure& callback, 253 const ErrorCallback& error_callback) 254 OVERRIDE { 255 dbus::MethodCall method_call( 256 bluetooth_device::kBluetoothDeviceInterface, 257 bluetooth_device::kCancelPairing); 258 259 dbus::ObjectProxy* object_proxy = 260 object_manager_->GetObjectProxy(object_path); 261 if (!object_proxy) { 262 error_callback.Run(kUnknownDeviceError, ""); 263 return; 264 } 265 object_proxy->CallMethodWithErrorCallback( 266 &method_call, 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)); 272 } 273 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); 281 282 dbus::ObjectProxy* object_proxy = 283 object_manager_->GetObjectProxy(object_path); 284 if (!object_proxy) { 285 error_callback.Run(kUnknownDeviceError, ""); 286 return; 287 } 288 object_proxy->CallMethodWithErrorCallback( 289 &method_call, 290 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 291 base::Bind(&BluetoothDeviceClientImpl::OnSuccess, 292 weak_ptr_factory_.GetWeakPtr(), 293 callback), 294 base::Bind(&BluetoothDeviceClientImpl::OnError, 295 weak_ptr_factory_.GetWeakPtr(), 296 error_callback)); 297 } 298 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); 306 307 dbus::ObjectProxy* object_proxy = 308 object_manager_->GetObjectProxy(object_path); 309 if (!object_proxy) { 310 error_callback.Run(kUnknownDeviceError, ""); 311 return; 312 } 313 object_proxy->CallMethodWithErrorCallback( 314 &method_call, 315 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 316 base::Bind(&BluetoothDeviceClientImpl::OnSuccess, 317 weak_ptr_factory_.GetWeakPtr(), 318 callback), 319 base::Bind(&BluetoothDeviceClientImpl::OnError, 320 weak_ptr_factory_.GetWeakPtr(), 321 error_callback)); 322 } 323 324 protected: 325 virtual void Init(dbus::Bus* bus) OVERRIDE { 326 object_manager_ = bus->GetObjectManager( 327 bluetooth_object_manager::kBluetoothObjectManagerServiceName, 328 dbus::ObjectPath( 329 bluetooth_object_manager::kBluetoothObjectManagerServicePath)); 330 object_manager_->RegisterInterface( 331 bluetooth_device::kBluetoothDeviceInterface, this); 332 } 333 334 private: 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)); 341 } 342 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)); 349 } 350 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)); 358 } 359 360 // Called when a response for successful method call is received. 361 void OnSuccess(const base::Closure& callback, 362 dbus::Response* response) { 363 DCHECK(response); 364 callback.Run(); 365 } 366 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; 373 if (response) { 374 dbus::MessageReader reader(response); 375 error_name = response->GetErrorName(); 376 reader.PopString(&error_message); 377 } else { 378 error_name = kNoResponseError; 379 error_message = ""; 380 } 381 error_callback.Run(error_name, error_message); 382 } 383 384 dbus::ObjectManager* object_manager_; 385 386 // List of observers interested in event notifications from us. 387 ObserverList<BluetoothDeviceClient::Observer> observers_; 388 389 // Weak pointer factory for generating 'this' pointers that might live longer 390 // than we do. 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_; 394 395 DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl); 396 }; 397 398 BluetoothDeviceClient::BluetoothDeviceClient() { 399 } 400 401 BluetoothDeviceClient::~BluetoothDeviceClient() { 402 } 403 404 BluetoothDeviceClient* BluetoothDeviceClient::Create() { 405 return new BluetoothDeviceClientImpl(); 406 } 407 408 } // namespace chromeos 409