| OLD | NEW |
| (Empty) |
| 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_proxy.h" | |
| 13 #include "third_party/cros_system_api/dbus/service_constants.h" | |
| 14 | |
| 15 namespace chromeos { | |
| 16 | |
| 17 BluetoothAdapterClient::DiscoveryFilter::DiscoveryFilter() { | |
| 18 } | |
| 19 | |
| 20 BluetoothAdapterClient::DiscoveryFilter::~DiscoveryFilter() { | |
| 21 } | |
| 22 | |
| 23 void BluetoothAdapterClient::DiscoveryFilter::CopyFrom( | |
| 24 const DiscoveryFilter& filter) { | |
| 25 if (filter.rssi.get()) | |
| 26 rssi.reset(new int16_t(*filter.rssi)); | |
| 27 else | |
| 28 rssi.reset(); | |
| 29 | |
| 30 if (filter.pathloss.get()) | |
| 31 pathloss.reset(new uint16_t(*filter.pathloss)); | |
| 32 else | |
| 33 pathloss.reset(); | |
| 34 | |
| 35 if (filter.transport.get()) | |
| 36 transport.reset(new std::string(*filter.transport)); | |
| 37 else | |
| 38 transport.reset(); | |
| 39 | |
| 40 if (filter.uuids.get()) | |
| 41 uuids.reset(new std::vector<std::string>(*filter.uuids)); | |
| 42 else | |
| 43 uuids.reset(); | |
| 44 } | |
| 45 | |
| 46 const char BluetoothAdapterClient::kNoResponseError[] = | |
| 47 "org.chromium.Error.NoResponse"; | |
| 48 const char BluetoothAdapterClient::kUnknownAdapterError[] = | |
| 49 "org.chromium.Error.UnknownAdapter"; | |
| 50 | |
| 51 BluetoothAdapterClient::Properties::Properties( | |
| 52 dbus::ObjectProxy* object_proxy, | |
| 53 const std::string& interface_name, | |
| 54 const PropertyChangedCallback& callback) | |
| 55 : dbus::PropertySet(object_proxy, interface_name, callback) { | |
| 56 RegisterProperty(bluetooth_adapter::kAddressProperty, &address); | |
| 57 RegisterProperty(bluetooth_adapter::kNameProperty, &name); | |
| 58 RegisterProperty(bluetooth_adapter::kAliasProperty, &alias); | |
| 59 RegisterProperty(bluetooth_adapter::kClassProperty, &bluetooth_class); | |
| 60 RegisterProperty(bluetooth_adapter::kPoweredProperty, &powered); | |
| 61 RegisterProperty(bluetooth_adapter::kDiscoverableProperty, &discoverable); | |
| 62 RegisterProperty(bluetooth_adapter::kPairableProperty, &pairable); | |
| 63 RegisterProperty(bluetooth_adapter::kPairableTimeoutProperty, | |
| 64 &pairable_timeout); | |
| 65 RegisterProperty(bluetooth_adapter::kDiscoverableTimeoutProperty, | |
| 66 &discoverable_timeout); | |
| 67 RegisterProperty(bluetooth_adapter::kDiscoveringProperty, &discovering); | |
| 68 RegisterProperty(bluetooth_adapter::kUUIDsProperty, &uuids); | |
| 69 RegisterProperty(bluetooth_adapter::kModaliasProperty, &modalias); | |
| 70 } | |
| 71 | |
| 72 BluetoothAdapterClient::Properties::~Properties() { | |
| 73 } | |
| 74 | |
| 75 | |
| 76 // The BluetoothAdapterClient implementation used in production. | |
| 77 class BluetoothAdapterClientImpl | |
| 78 : public BluetoothAdapterClient, | |
| 79 public dbus::ObjectManager::Interface { | |
| 80 public: | |
| 81 BluetoothAdapterClientImpl() | |
| 82 : object_manager_(NULL), weak_ptr_factory_(this) {} | |
| 83 | |
| 84 ~BluetoothAdapterClientImpl() override { | |
| 85 object_manager_->UnregisterInterface( | |
| 86 bluetooth_adapter::kBluetoothAdapterInterface); | |
| 87 } | |
| 88 | |
| 89 // BluetoothAdapterClient override. | |
| 90 void AddObserver(BluetoothAdapterClient::Observer* observer) override { | |
| 91 DCHECK(observer); | |
| 92 observers_.AddObserver(observer); | |
| 93 } | |
| 94 | |
| 95 // BluetoothAdapterClient override. | |
| 96 void RemoveObserver(BluetoothAdapterClient::Observer* observer) override { | |
| 97 DCHECK(observer); | |
| 98 observers_.RemoveObserver(observer); | |
| 99 } | |
| 100 | |
| 101 // Returns the list of adapter object paths known to the system. | |
| 102 std::vector<dbus::ObjectPath> GetAdapters() override { | |
| 103 return object_manager_->GetObjectsWithInterface( | |
| 104 bluetooth_adapter::kBluetoothAdapterInterface); | |
| 105 } | |
| 106 | |
| 107 // dbus::ObjectManager::Interface override. | |
| 108 dbus::PropertySet* CreateProperties( | |
| 109 dbus::ObjectProxy* object_proxy, | |
| 110 const dbus::ObjectPath& object_path, | |
| 111 const std::string& interface_name) override { | |
| 112 Properties* properties = new Properties( | |
| 113 object_proxy, | |
| 114 interface_name, | |
| 115 base::Bind(&BluetoothAdapterClientImpl::OnPropertyChanged, | |
| 116 weak_ptr_factory_.GetWeakPtr(), | |
| 117 object_path)); | |
| 118 return static_cast<dbus::PropertySet*>(properties); | |
| 119 } | |
| 120 | |
| 121 // BluetoothAdapterClient override. | |
| 122 Properties* GetProperties(const dbus::ObjectPath& object_path) override { | |
| 123 return static_cast<Properties*>( | |
| 124 object_manager_->GetProperties( | |
| 125 object_path, | |
| 126 bluetooth_adapter::kBluetoothAdapterInterface)); | |
| 127 } | |
| 128 | |
| 129 // BluetoothAdapterClient override. | |
| 130 void StartDiscovery(const dbus::ObjectPath& object_path, | |
| 131 const base::Closure& callback, | |
| 132 const ErrorCallback& error_callback) override { | |
| 133 dbus::MethodCall method_call( | |
| 134 bluetooth_adapter::kBluetoothAdapterInterface, | |
| 135 bluetooth_adapter::kStartDiscovery); | |
| 136 | |
| 137 dbus::ObjectProxy* object_proxy = | |
| 138 object_manager_->GetObjectProxy(object_path); | |
| 139 if (!object_proxy) { | |
| 140 error_callback.Run(kUnknownAdapterError, ""); | |
| 141 return; | |
| 142 } | |
| 143 | |
| 144 object_proxy->CallMethodWithErrorCallback( | |
| 145 &method_call, | |
| 146 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 147 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, | |
| 148 weak_ptr_factory_.GetWeakPtr(), callback), | |
| 149 base::Bind(&BluetoothAdapterClientImpl::OnError, | |
| 150 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
| 151 } | |
| 152 | |
| 153 // BluetoothAdapterClient override. | |
| 154 void StopDiscovery(const dbus::ObjectPath& object_path, | |
| 155 const base::Closure& callback, | |
| 156 const ErrorCallback& error_callback) override { | |
| 157 dbus::MethodCall method_call( | |
| 158 bluetooth_adapter::kBluetoothAdapterInterface, | |
| 159 bluetooth_adapter::kStopDiscovery); | |
| 160 | |
| 161 dbus::ObjectProxy* object_proxy = | |
| 162 object_manager_->GetObjectProxy(object_path); | |
| 163 if (!object_proxy) { | |
| 164 error_callback.Run(kUnknownAdapterError, ""); | |
| 165 return; | |
| 166 } | |
| 167 | |
| 168 object_proxy->CallMethodWithErrorCallback( | |
| 169 &method_call, | |
| 170 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 171 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, | |
| 172 weak_ptr_factory_.GetWeakPtr(), callback), | |
| 173 base::Bind(&BluetoothAdapterClientImpl::OnError, | |
| 174 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
| 175 } | |
| 176 | |
| 177 // BluetoothAdapterClient override. | |
| 178 void RemoveDevice(const dbus::ObjectPath& object_path, | |
| 179 const dbus::ObjectPath& device_path, | |
| 180 const base::Closure& callback, | |
| 181 const ErrorCallback& error_callback) override { | |
| 182 dbus::MethodCall method_call( | |
| 183 bluetooth_adapter::kBluetoothAdapterInterface, | |
| 184 bluetooth_adapter::kRemoveDevice); | |
| 185 | |
| 186 dbus::MessageWriter writer(&method_call); | |
| 187 writer.AppendObjectPath(device_path); | |
| 188 | |
| 189 dbus::ObjectProxy* object_proxy = | |
| 190 object_manager_->GetObjectProxy(object_path); | |
| 191 if (!object_proxy) { | |
| 192 error_callback.Run(kUnknownAdapterError, ""); | |
| 193 return; | |
| 194 } | |
| 195 | |
| 196 object_proxy->CallMethodWithErrorCallback( | |
| 197 &method_call, | |
| 198 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 199 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, | |
| 200 weak_ptr_factory_.GetWeakPtr(), callback), | |
| 201 base::Bind(&BluetoothAdapterClientImpl::OnError, | |
| 202 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
| 203 } | |
| 204 | |
| 205 // BluetoothAdapterClient override. | |
| 206 void SetDiscoveryFilter(const dbus::ObjectPath& object_path, | |
| 207 const DiscoveryFilter& discovery_filter, | |
| 208 const base::Closure& callback, | |
| 209 const ErrorCallback& error_callback) override { | |
| 210 dbus::MethodCall method_call(bluetooth_adapter::kBluetoothAdapterInterface, | |
| 211 bluetooth_adapter::kSetDiscoveryFilter); | |
| 212 | |
| 213 dbus::MessageWriter writer(&method_call); | |
| 214 dbus::MessageWriter dict_writer(nullptr); | |
| 215 | |
| 216 dbus::ObjectProxy* object_proxy = | |
| 217 object_manager_->GetObjectProxy(object_path); | |
| 218 if (!object_proxy) { | |
| 219 error_callback.Run(kUnknownAdapterError, ""); | |
| 220 return; | |
| 221 } | |
| 222 | |
| 223 writer.OpenArray("{sv}", &dict_writer); | |
| 224 | |
| 225 if (discovery_filter.uuids.get()) { | |
| 226 std::vector<std::string>* uuids = discovery_filter.uuids.get(); | |
| 227 dbus::MessageWriter uuids_entry_writer(nullptr); | |
| 228 dict_writer.OpenDictEntry(&uuids_entry_writer); | |
| 229 uuids_entry_writer.AppendString( | |
| 230 bluetooth_adapter::kDiscoveryFilterParameterUUIDs); | |
| 231 | |
| 232 dbus::MessageWriter uuids_array_variant(nullptr); | |
| 233 uuids_entry_writer.OpenVariant("as", &uuids_array_variant); | |
| 234 dbus::MessageWriter uuids_array(nullptr); | |
| 235 uuids_array_variant.OpenArray("s", &uuids_array); | |
| 236 | |
| 237 for (auto& it : *uuids) | |
| 238 uuids_array.AppendString(it); | |
| 239 | |
| 240 uuids_array_variant.CloseContainer(&uuids_array); | |
| 241 uuids_entry_writer.CloseContainer(&uuids_array_variant); | |
| 242 dict_writer.CloseContainer(&uuids_entry_writer); | |
| 243 } | |
| 244 | |
| 245 if (discovery_filter.rssi.get()) { | |
| 246 dbus::MessageWriter rssi_entry_writer(nullptr); | |
| 247 dict_writer.OpenDictEntry(&rssi_entry_writer); | |
| 248 rssi_entry_writer.AppendString( | |
| 249 bluetooth_adapter::kDiscoveryFilterParameterRSSI); | |
| 250 rssi_entry_writer.AppendVariantOfInt16(*discovery_filter.rssi.get()); | |
| 251 dict_writer.CloseContainer(&rssi_entry_writer); | |
| 252 } | |
| 253 | |
| 254 if (discovery_filter.pathloss.get()) { | |
| 255 dbus::MessageWriter pathloss_entry_writer(nullptr); | |
| 256 dict_writer.OpenDictEntry(&pathloss_entry_writer); | |
| 257 pathloss_entry_writer.AppendString( | |
| 258 bluetooth_adapter::kDiscoveryFilterParameterPathloss); | |
| 259 pathloss_entry_writer.AppendVariantOfUint16( | |
| 260 *discovery_filter.pathloss.get()); | |
| 261 dict_writer.CloseContainer(&pathloss_entry_writer); | |
| 262 } | |
| 263 | |
| 264 if (discovery_filter.transport.get()) { | |
| 265 dbus::MessageWriter transport_entry_writer(nullptr); | |
| 266 dict_writer.OpenDictEntry(&transport_entry_writer); | |
| 267 transport_entry_writer.AppendString( | |
| 268 bluetooth_adapter::kDiscoveryFilterParameterTransport); | |
| 269 transport_entry_writer.AppendVariantOfString( | |
| 270 *discovery_filter.transport.get()); | |
| 271 dict_writer.CloseContainer(&transport_entry_writer); | |
| 272 } | |
| 273 | |
| 274 writer.CloseContainer(&dict_writer); | |
| 275 | |
| 276 object_proxy->CallMethodWithErrorCallback( | |
| 277 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
| 278 base::Bind(&BluetoothAdapterClientImpl::OnSuccess, | |
| 279 weak_ptr_factory_.GetWeakPtr(), callback), | |
| 280 base::Bind(&BluetoothAdapterClientImpl::OnError, | |
| 281 weak_ptr_factory_.GetWeakPtr(), error_callback)); | |
| 282 } | |
| 283 | |
| 284 protected: | |
| 285 void Init(dbus::Bus* bus) override { | |
| 286 object_manager_ = bus->GetObjectManager( | |
| 287 bluetooth_object_manager::kBluetoothObjectManagerServiceName, | |
| 288 dbus::ObjectPath( | |
| 289 bluetooth_object_manager::kBluetoothObjectManagerServicePath)); | |
| 290 object_manager_->RegisterInterface( | |
| 291 bluetooth_adapter::kBluetoothAdapterInterface, this); | |
| 292 } | |
| 293 | |
| 294 private: | |
| 295 // Called by dbus::ObjectManager when an object with the adapter interface | |
| 296 // is created. Informs observers. | |
| 297 void ObjectAdded(const dbus::ObjectPath& object_path, | |
| 298 const std::string& interface_name) override { | |
| 299 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, | |
| 300 AdapterAdded(object_path)); | |
| 301 } | |
| 302 | |
| 303 // Called by dbus::ObjectManager when an object with the adapter interface | |
| 304 // is removed. Informs observers. | |
| 305 void ObjectRemoved(const dbus::ObjectPath& object_path, | |
| 306 const std::string& interface_name) override { | |
| 307 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, | |
| 308 AdapterRemoved(object_path)); | |
| 309 } | |
| 310 | |
| 311 // Called by dbus::PropertySet when a property value is changed, | |
| 312 // either by result of a signal or response to a GetAll() or Get() | |
| 313 // call. Informs observers. | |
| 314 void OnPropertyChanged(const dbus::ObjectPath& object_path, | |
| 315 const std::string& property_name) { | |
| 316 FOR_EACH_OBSERVER(BluetoothAdapterClient::Observer, observers_, | |
| 317 AdapterPropertyChanged(object_path, property_name)); | |
| 318 } | |
| 319 | |
| 320 // Called when a response for successful method call is received. | |
| 321 void OnSuccess(const base::Closure& callback, | |
| 322 dbus::Response* response) { | |
| 323 DCHECK(response); | |
| 324 callback.Run(); | |
| 325 } | |
| 326 | |
| 327 // Called when a response for a failed method call is received. | |
| 328 void OnError(const ErrorCallback& error_callback, | |
| 329 dbus::ErrorResponse* response) { | |
| 330 // Error response has optional error message argument. | |
| 331 std::string error_name; | |
| 332 std::string error_message; | |
| 333 if (response) { | |
| 334 dbus::MessageReader reader(response); | |
| 335 error_name = response->GetErrorName(); | |
| 336 reader.PopString(&error_message); | |
| 337 } else { | |
| 338 error_name = kNoResponseError; | |
| 339 error_message = ""; | |
| 340 } | |
| 341 error_callback.Run(error_name, error_message); | |
| 342 } | |
| 343 | |
| 344 dbus::ObjectManager* object_manager_; | |
| 345 | |
| 346 // List of observers interested in event notifications from us. | |
| 347 base::ObserverList<BluetoothAdapterClient::Observer> observers_; | |
| 348 | |
| 349 // Weak pointer factory for generating 'this' pointers that might live longer | |
| 350 // than we do. | |
| 351 // Note: This should remain the last member so it'll be destroyed and | |
| 352 // invalidate its weak pointers before any other members are destroyed. | |
| 353 base::WeakPtrFactory<BluetoothAdapterClientImpl> | |
| 354 weak_ptr_factory_; | |
| 355 | |
| 356 DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl); | |
| 357 }; | |
| 358 | |
| 359 BluetoothAdapterClient::BluetoothAdapterClient() { | |
| 360 } | |
| 361 | |
| 362 BluetoothAdapterClient::~BluetoothAdapterClient() { | |
| 363 } | |
| 364 | |
| 365 BluetoothAdapterClient* BluetoothAdapterClient::Create() { | |
| 366 return new BluetoothAdapterClientImpl; | |
| 367 } | |
| 368 | |
| 369 } // namespace chromeos | |
| OLD | NEW |