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