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_adapter_client.h" 6 7#include "base/bind.h" 8#include "base/logging.h" 9#include "dbus/bus.h" 10#include "dbus/message.h" 11#include "dbus/object_manager.h" 12#include "dbus/object_path.h" 13#include "dbus/object_proxy.h" 14#include "third_party/cros_system_api/dbus/service_constants.h" 15 16namespace chromeos { 17 18const char BluetoothAdapterClient::kNoResponseError[] = 19 "org.chromium.Error.NoResponse"; 20const char BluetoothAdapterClient::kUnknownAdapterError[] = 21 "org.chromium.Error.UnknownAdapter"; 22 23BluetoothAdapterClient::Properties::Properties( 24 dbus::ObjectProxy* object_proxy, 25 const std::string& interface_name, 26 const PropertyChangedCallback& callback) 27 : dbus::PropertySet(object_proxy, interface_name, callback) { 28 RegisterProperty(bluetooth_adapter::kAddressProperty, &address); 29 RegisterProperty(bluetooth_adapter::kNameProperty, &name); 30 RegisterProperty(bluetooth_adapter::kAliasProperty, &alias); 31 RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class); 32 RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered); 33 RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable); 34 RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable); 35 RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty, 36 &pairable_timeout); 37 RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty, 38 &discoverable_timeout); 39 RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering); 40 RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids); 41 RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias); 42} 43 44BluetoothAdapterClient::Properties::~Properties() { 45} 46 47 48// The BluetoothAdapterClient implementation used in production. 49class BluetoothAdapterClientImpl 50 : public BluetoothAdapterClient, 51 public dbus::ObjectManager::Interface { 52 public: 53 BluetoothAdapterClientImpl() : weak_ptr_factory_(this) {} 54 55 virtual ~BluetoothAdapterClientImpl() { 56 object_manager_->UnregisterInterface( 57 bluetooth_adapter::kBluetoothAdapterInterface); 58 } 59 60 // BluetoothAdapterClient override. 61 virtual void AddObserver(BluetoothAdapterClient::Observer* observer) 62 OVERRIDE { 63 DCHECK(observer); 64 observers_.AddObserver(observer); 65 } 66 67 // BluetoothAdapterClient override. 68 virtual void RemoveObserver(BluetoothAdapterClient::Observer* observer) 69 OVERRIDE { 70 DCHECK(observer); 71 observers_.RemoveObserver(observer); 72 } 73 74 // Returns the list of adapter object paths known to the system. 75 virtual std::vector<dbus::ObjectPath> GetAdapters() OVERRIDE { 76 return object_manager_->GetObjectsWithInterface( 77 bluetooth_adapter::kBluetoothAdapterInterface); 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(&BluetoothAdapterClientImpl::OnPropertyChanged, 89 weak_ptr_factory_.GetWeakPtr(), 90 object_path)); 91 return static_cast<dbus::PropertySet*>(properties); 92 } 93 94 // BluetoothAdapterClient override. 95 virtual Properties* GetProperties(const dbus::ObjectPath& object_path) 96 OVERRIDE { 97 return static_cast<Properties*>( 98 object_manager_->GetProperties( 99 object_path, 100 bluetooth_adapter::kBluetoothAdapterInterface)); 101 } 102 103 // BluetoothAdapterClient override. 104 virtual void StartDiscovery(const dbus::ObjectPath& object_path, 105 const base::Closure& callback, 106 const ErrorCallback& error_callback) OVERRIDE { 107 dbus::MethodCall method_call( 108 bluetooth_adapter::kBluetoothAdapterInterface, 109 bluetooth_adapter::kStartDiscovery); 110 111 dbus::ObjectProxy* object_proxy = 112 object_manager_->GetObjectProxy(object_path); 113 if (!object_proxy) { 114 error_callback.Run(kUnknownAdapterError, ""); 115 return; 116 } 117 118 object_proxy->CallMethodWithErrorCallback( 119 &method_call, 120 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 121 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, 122 weak_ptr_factory_.GetWeakPtr(), callback), 123 base::Bind(&BluetoothAdapterClientImpl::OnError, 124 weak_ptr_factory_.GetWeakPtr(), error_callback)); 125 } 126 127 // BluetoothAdapterClient override. 128 virtual void StopDiscovery(const dbus::ObjectPath& object_path, 129 const base::Closure& callback, 130 const ErrorCallback& error_callback) OVERRIDE { 131 dbus::MethodCall method_call( 132 bluetooth_adapter::kBluetoothAdapterInterface, 133 bluetooth_adapter::kStopDiscovery); 134 135 dbus::ObjectProxy* object_proxy = 136 object_manager_->GetObjectProxy(object_path); 137 if (!object_proxy) { 138 error_callback.Run(kUnknownAdapterError, ""); 139 return; 140 } 141 142 object_proxy->CallMethodWithErrorCallback( 143 &method_call, 144 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 145 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, 146 weak_ptr_factory_.GetWeakPtr(), callback), 147 base::Bind(&BluetoothAdapterClientImpl::OnError, 148 weak_ptr_factory_.GetWeakPtr(), error_callback)); 149 } 150 151 // BluetoothAdapterClient override. 152 virtual void RemoveDevice(const dbus::ObjectPath& object_path, 153 const dbus::ObjectPath& device_path, 154 const base::Closure& callback, 155 const ErrorCallback& error_callback) OVERRIDE { 156 dbus::MethodCall method_call( 157 bluetooth_adapter::kBluetoothAdapterInterface, 158 bluetooth_adapter::kRemoveDevice); 159 160 dbus::MessageWriter writer(&method_call); 161 writer.AppendObjectPath(device_path); 162 163 dbus::ObjectProxy* object_proxy = 164 object_manager_->GetObjectProxy(object_path); 165 if (!object_proxy) { 166 error_callback.Run(kUnknownAdapterError, ""); 167 return; 168 } 169 170 object_proxy->CallMethodWithErrorCallback( 171 &method_call, 172 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, 173 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, 174 weak_ptr_factory_.GetWeakPtr(), callback), 175 base::Bind(&BluetoothAdapterClientImpl::OnError, 176 weak_ptr_factory_.GetWeakPtr(), error_callback)); 177 } 178 179 protected: 180 virtual void Init(dbus::Bus* bus) OVERRIDE { 181 object_manager_ = bus->GetObjectManager( 182 bluetooth_object_manager::kBluetoothObjectManagerServiceName, 183 dbus::ObjectPath( 184 bluetooth_object_manager::kBluetoothObjectManagerServicePath)); 185 object_manager_->RegisterInterface( 186 bluetooth_adapter::kBluetoothAdapterInterface, this); 187 } 188 189 private: 190 // Called by dbus::ObjectManager when an object with the adapter interface 191 // is created. Informs observers. 192 virtual void ObjectAdded(const dbus::ObjectPath& object_path, 193 const std::string& interface_name) OVERRIDE { 194 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 195 AdapterAdded(object_path)); 196 } 197 198 // Called by dbus::ObjectManager when an object with the adapter interface 199 // is removed. Informs observers. 200 virtual void ObjectRemoved(const dbus::ObjectPath& object_path, 201 const std::string& interface_name) OVERRIDE { 202 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 203 AdapterRemoved(object_path)); 204 } 205 206 // Called by dbus::PropertySet when a property value is changed, 207 // either by result of a signal or response to a GetAll() or Get() 208 // call. Informs observers. 209 void OnPropertyChanged(const dbus::ObjectPath& object_path, 210 const std::string& property_name) { 211 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, 212 AdapterPropertyChanged(object_path, property_name)); 213 } 214 215 // Called when a response for successful method call is received. 216 void OnSuccess(const base::Closure& callback, 217 dbus::Response* response) { 218 DCHECK(response); 219 callback.Run(); 220 } 221 222 // Called when a response for a failed method call is received. 223 void OnError(const ErrorCallback& error_callback, 224 dbus::ErrorResponse* response) { 225 // Error response has optional error message argument. 226 std::string error_name; 227 std::string error_message; 228 if (response) { 229 dbus::MessageReader reader(response); 230 error_name = response->GetErrorName(); 231 reader.PopString(&error_message); 232 } else { 233 error_name = kNoResponseError; 234 error_message = ""; 235 } 236 error_callback.Run(error_name, error_message); 237 } 238 239 dbus::ObjectManager* object_manager_; 240 241 // List of observers interested in event notifications from us. 242 ObserverList<BluetoothAdapterClient::Observer> observers_; 243 244 // Weak pointer factory for generating 'this' pointers that might live longer 245 // than we do. 246 // Note: This should remain the last member so it'll be destroyed and 247 // invalidate its weak pointers before any other members are destroyed. 248 base::WeakPtrFactory<BluetoothAdapterClientImpl> 249 weak_ptr_factory_; 250 251 DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl); 252}; 253 254BluetoothAdapterClient::BluetoothAdapterClient() { 255} 256 257BluetoothAdapterClient::~BluetoothAdapterClient() { 258} 259 260BluetoothAdapterClient* BluetoothAdapterClient::Create() { 261 return new BluetoothAdapterClientImpl; 262} 263 264} // namespace chromeos 265