Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h " | 5 #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h " |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | |
| 10 #include <utility> | |
| 11 | |
| 12 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/callback.h" | |
| 13 #include "base/logging.h" | 11 #include "base/logging.h" |
| 14 #include "base/macros.h" | 12 #include "base/memory/ref_counted.h" |
| 15 #include "base/memory/weak_ptr.h" | 13 #include "base/memory/weak_ptr.h" |
| 16 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 17 #include "base/threading/platform_thread.h" | 15 #include "base/threading/platform_thread.h" |
| 18 #include "dbus/exported_object.h" | 16 #include "dbus/exported_object.h" |
| 19 #include "dbus/message.h" | |
| 20 #include "device/bluetooth/dbus/bluez_dbus_manager.h" | 17 #include "device/bluetooth/dbus/bluez_dbus_manager.h" |
| 21 #include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provi der.h" | 18 #include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provi der.h" |
| 22 #include "third_party/cros_system_api/dbus/service_constants.h" | 19 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 23 | 20 |
| 24 namespace bluez { | 21 namespace bluez { |
| 25 namespace { | 22 namespace { |
| 26 const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs"; | 23 const char kErrorInvalidArgs[] = "org.freedesktop.DBus.Error.InvalidArgs"; |
| 27 const char kErrorPropertyReadOnly[] = | 24 const char kErrorPropertyReadOnly[] = |
| 28 "org.freedesktop.DBus.Error.PropertyReadOnly"; | 25 "org.freedesktop.DBus.Error.PropertyReadOnly"; |
| 29 const char kErrorFailed[] = "org.freedesktop.DBus.Error.Failed"; | 26 const char kErrorFailed[] = "org.freedesktop.DBus.Error.Failed"; |
| 30 } // namespace | 27 } // namespace |
| 31 | 28 |
| 32 // The BluetoothGattCharacteristicServiceProvider implementation used in | 29 // The BluetoothGattCharacteristicServiceProvider implementation used in |
| 33 // production. | 30 // production. |
| 34 class BluetoothGattCharacteristicServiceProviderImpl | 31 class BluetoothGattCharacteristicServiceProviderImpl |
| 35 : public BluetoothGattCharacteristicServiceProvider { | 32 : public BluetoothGattCharacteristicServiceProvider { |
| 36 public: | 33 public: |
| 37 BluetoothGattCharacteristicServiceProviderImpl( | 34 BluetoothGattCharacteristicServiceProviderImpl( |
| 38 dbus::Bus* bus, | 35 dbus::Bus* bus, |
| 39 const dbus::ObjectPath& object_path, | 36 const dbus::ObjectPath& object_path, |
| 40 Delegate* delegate, | 37 std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate, |
| 41 const std::string& uuid, | 38 const std::string& uuid, |
| 42 const std::vector<std::string>& flags, | 39 const std::vector<std::string>& flags, |
| 43 const std::vector<std::string>& permissions, | 40 const std::vector<std::string>& permissions, |
| 44 const dbus::ObjectPath& service_path) | 41 const dbus::ObjectPath& service_path) |
| 45 : origin_thread_id_(base::PlatformThread::CurrentId()), | 42 : origin_thread_id_(base::PlatformThread::CurrentId()), |
| 46 uuid_(uuid), | 43 uuid_(uuid), |
| 47 bus_(bus), | 44 bus_(bus), |
| 48 delegate_(delegate), | 45 delegate_(std::move(delegate)), |
| 49 object_path_(object_path), | 46 object_path_(object_path), |
| 50 service_path_(service_path), | 47 service_path_(service_path), |
| 51 weak_ptr_factory_(this) { | 48 weak_ptr_factory_(this) { |
| 52 VLOG(1) << "Created Bluetooth GATT characteristic: " << object_path.value() | 49 VLOG(1) << "Created Bluetooth GATT characteristic: " << object_path.value() |
| 53 << " UUID: " << uuid; | 50 << " UUID: " << uuid; |
| 54 DCHECK(bus_); | 51 DCHECK(bus_); |
| 55 DCHECK(delegate_); | 52 DCHECK(delegate_); |
| 56 DCHECK(!uuid_.empty()); | 53 DCHECK(!uuid_.empty()); |
| 57 DCHECK(object_path_.IsValid()); | 54 DCHECK(object_path_.IsValid()); |
| 58 DCHECK(service_path_.IsValid()); | 55 DCHECK(service_path_.IsValid()); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 dbus::ErrorResponse::FromMethodCall( | 152 dbus::ErrorResponse::FromMethodCall( |
| 156 method_call, kErrorInvalidArgs, | 153 method_call, kErrorInvalidArgs, |
| 157 "No such interface: '" + interface_name + "'."); | 154 "No such interface: '" + interface_name + "'."); |
| 158 response_sender.Run(std::move(error_response)); | 155 response_sender.Run(std::move(error_response)); |
| 159 return; | 156 return; |
| 160 } | 157 } |
| 161 | 158 |
| 162 // If getting the "Value" property, obtain the value from the delegate. | 159 // If getting the "Value" property, obtain the value from the delegate. |
| 163 if (property_name == bluetooth_gatt_characteristic::kValueProperty) { | 160 if (property_name == bluetooth_gatt_characteristic::kValueProperty) { |
| 164 DCHECK(delegate_); | 161 DCHECK(delegate_); |
| 165 delegate_->GetCharacteristicValue( | 162 delegate_->GetValue( |
| 166 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGet, | 163 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGet, |
| 167 weak_ptr_factory_.GetWeakPtr(), method_call, | 164 weak_ptr_factory_.GetWeakPtr(), method_call, |
| 168 response_sender), | 165 response_sender), |
| 169 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, | 166 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, |
| 170 weak_ptr_factory_.GetWeakPtr(), method_call, | 167 weak_ptr_factory_.GetWeakPtr(), method_call, |
| 171 response_sender)); | 168 response_sender)); |
| 172 return; | 169 return; |
| 173 } | 170 } |
| 174 | 171 |
| 175 std::unique_ptr<dbus::Response> response = | 172 std::unique_ptr<dbus::Response> response = |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 257 dbus::ErrorResponse::FromMethodCall( | 254 dbus::ErrorResponse::FromMethodCall( |
| 258 method_call, kErrorInvalidArgs, | 255 method_call, kErrorInvalidArgs, |
| 259 "Property '" + property_name + "' has type 'ay'."); | 256 "Property '" + property_name + "' has type 'ay'."); |
| 260 response_sender.Run(std::move(error_response)); | 257 response_sender.Run(std::move(error_response)); |
| 261 return; | 258 return; |
| 262 } | 259 } |
| 263 | 260 |
| 264 // Pass the set request onto the delegate. | 261 // Pass the set request onto the delegate. |
| 265 std::vector<uint8_t> value(bytes, bytes + length); | 262 std::vector<uint8_t> value(bytes, bytes + length); |
| 266 DCHECK(delegate_); | 263 DCHECK(delegate_); |
| 267 delegate_->SetCharacteristicValue( | 264 delegate_->SetValue( |
| 268 value, | 265 value, |
| 269 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnSet, | 266 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnSet, |
| 270 weak_ptr_factory_.GetWeakPtr(), method_call, | 267 weak_ptr_factory_.GetWeakPtr(), method_call, |
| 271 response_sender), | 268 response_sender), |
| 272 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, | 269 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, |
| 273 weak_ptr_factory_.GetWeakPtr(), method_call, | 270 weak_ptr_factory_.GetWeakPtr(), method_call, |
| 274 response_sender)); | 271 response_sender)); |
| 275 } | 272 } |
| 276 | 273 |
| 277 // Called by dbus:: when the Bluetooth daemon fetches all properties of the | 274 // Called by dbus:: when the Bluetooth daemon fetches all properties of the |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 300 dbus::ErrorResponse::FromMethodCall( | 297 dbus::ErrorResponse::FromMethodCall( |
| 301 method_call, kErrorInvalidArgs, | 298 method_call, kErrorInvalidArgs, |
| 302 "No such interface: '" + interface_name + "'."); | 299 "No such interface: '" + interface_name + "'."); |
| 303 response_sender.Run(std::move(error_response)); | 300 response_sender.Run(std::move(error_response)); |
| 304 return; | 301 return; |
| 305 } | 302 } |
| 306 | 303 |
| 307 // Try to obtain the value from the delegate. We will construct the | 304 // Try to obtain the value from the delegate. We will construct the |
| 308 // response in the success callback. | 305 // response in the success callback. |
| 309 DCHECK(delegate_); | 306 DCHECK(delegate_); |
| 310 delegate_->GetCharacteristicValue( | 307 delegate_->GetValue( |
| 311 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGetAll, | 308 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnGetAll, |
| 312 weak_ptr_factory_.GetWeakPtr(), method_call, | 309 weak_ptr_factory_.GetWeakPtr(), method_call, |
| 313 response_sender), | 310 response_sender), |
| 314 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, | 311 base::Bind(&BluetoothGattCharacteristicServiceProviderImpl::OnFailure, |
| 315 weak_ptr_factory_.GetWeakPtr(), method_call, | 312 weak_ptr_factory_.GetWeakPtr(), method_call, |
| 316 response_sender)); | 313 response_sender)); |
| 317 } | 314 } |
| 318 | 315 |
| 319 // Called by dbus:: when a method is exported. | 316 // Called by dbus:: when a method is exported. |
| 320 void OnExported(const std::string& interface_name, | 317 void OnExported(const std::string& interface_name, |
| 321 const std::string& method_name, | 318 const std::string& method_name, |
| 322 bool success) { | 319 bool success) { |
| 323 LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "." | 320 LOG_IF(WARNING, !success) << "Failed to export " << interface_name << "." |
| 324 << method_name; | 321 << method_name; |
| 325 } | 322 } |
| 326 | 323 |
| 327 // Called by the Delegate in response to a method to call to get all | 324 // Called by the Delegate in response to a method to call to get all |
| 328 // properties, in which the delegate has successfully returned the | 325 // properties, in which the delegate has successfully returned the |
| 329 // characteristic value. | 326 // characteristic value. |
| 330 void OnGetAll(dbus::MethodCall* method_call, | 327 void OnGetAll(dbus::MethodCall* method_call, |
| 331 dbus::ExportedObject::ResponseSender response_sender, | 328 dbus::ExportedObject::ResponseSender response_sender, |
| 332 const std::vector<uint8_t>& value) { | 329 const std::vector<uint8_t>& value) { |
| 333 VLOG(2) << "Characteristic value obtained from delegate. Responding to " | 330 VLOG(2) << "Characteristic value obtained from delegate. Responding to " |
| 334 << "GetAll."; | 331 << "GetAll."; |
| 335 | 332 |
| 336 std::unique_ptr<dbus::Response> response = | 333 std::unique_ptr<dbus::Response> response = |
| 337 dbus::Response::FromMethodCall(method_call); | 334 dbus::Response::FromMethodCall(method_call); |
|
scheib
2016/04/28 04:54:28
Are protections against the callback being called
rkc
2016/04/28 18:13:23
I'm pretty certain that our DBus client code has p
| |
| 338 dbus::MessageWriter writer(response.get()); | 335 dbus::MessageWriter writer(response.get()); |
| 336 WriteProperties(&writer, &value); | |
| 337 response_sender.Run(std::move(response)); | |
| 338 } | |
| 339 | |
| 340 // Writes an array of the service's properties into the provided writer. | |
| 341 void WriteProperties(dbus::MessageWriter* writer, | |
| 342 const std::vector<uint8_t>* value) override { | |
| 339 dbus::MessageWriter array_writer(NULL); | 343 dbus::MessageWriter array_writer(NULL); |
| 340 dbus::MessageWriter dict_entry_writer(NULL); | 344 dbus::MessageWriter dict_entry_writer(NULL); |
| 341 dbus::MessageWriter variant_writer(NULL); | 345 dbus::MessageWriter variant_writer(NULL); |
| 342 | 346 |
| 343 writer.OpenArray("{sv}", &array_writer); | 347 writer->OpenArray("{sv}", &array_writer); |
| 344 | 348 |
| 345 array_writer.OpenDictEntry(&dict_entry_writer); | 349 array_writer.OpenDictEntry(&dict_entry_writer); |
| 346 dict_entry_writer.AppendString( | 350 dict_entry_writer.AppendString( |
| 347 bluetooth_gatt_characteristic::kUUIDProperty); | 351 bluetooth_gatt_characteristic::kUUIDProperty); |
| 348 dict_entry_writer.AppendVariantOfString(uuid_); | 352 dict_entry_writer.AppendVariantOfString(uuid_); |
| 349 array_writer.CloseContainer(&dict_entry_writer); | 353 array_writer.CloseContainer(&dict_entry_writer); |
| 350 | 354 |
| 351 array_writer.OpenDictEntry(&dict_entry_writer); | 355 array_writer.OpenDictEntry(&dict_entry_writer); |
| 352 dict_entry_writer.AppendString( | 356 dict_entry_writer.AppendString( |
| 353 bluetooth_gatt_characteristic::kServiceProperty); | 357 bluetooth_gatt_characteristic::kServiceProperty); |
| 354 dict_entry_writer.AppendVariantOfObjectPath(service_path_); | 358 dict_entry_writer.AppendVariantOfObjectPath(service_path_); |
| 355 array_writer.CloseContainer(&dict_entry_writer); | 359 array_writer.CloseContainer(&dict_entry_writer); |
| 356 | 360 |
| 357 array_writer.OpenDictEntry(&dict_entry_writer); | 361 if (value) { |
| 358 dict_entry_writer.AppendString( | 362 array_writer.OpenDictEntry(&dict_entry_writer); |
| 359 bluetooth_gatt_characteristic::kValueProperty); | 363 dict_entry_writer.AppendString( |
| 360 dict_entry_writer.OpenVariant("ay", &variant_writer); | 364 bluetooth_gatt_characteristic::kValueProperty); |
| 361 variant_writer.AppendArrayOfBytes(value.data(), value.size()); | 365 dict_entry_writer.OpenVariant("ay", &variant_writer); |
| 362 dict_entry_writer.CloseContainer(&variant_writer); | 366 variant_writer.AppendArrayOfBytes(value->data(), value->size()); |
| 363 array_writer.CloseContainer(&dict_entry_writer); | 367 dict_entry_writer.CloseContainer(&variant_writer); |
| 368 array_writer.CloseContainer(&dict_entry_writer); | |
| 369 } | |
| 364 | 370 |
| 365 // TODO(armansito): Process Flags & Permissions properties. | 371 // TODO(armansito): Process Flags & Permissions properties. |
| 366 | 372 |
| 367 writer.CloseContainer(&array_writer); | 373 writer->CloseContainer(&array_writer); |
| 368 | 374 }; |
| 369 response_sender.Run(std::move(response)); | |
| 370 } | |
| 371 | 375 |
| 372 // Called by the Delegate in response to a successful method call to get the | 376 // Called by the Delegate in response to a successful method call to get the |
| 373 // characteristic value. | 377 // characteristic value. |
| 374 void OnGet(dbus::MethodCall* method_call, | 378 void OnGet(dbus::MethodCall* method_call, |
| 375 dbus::ExportedObject::ResponseSender response_sender, | 379 dbus::ExportedObject::ResponseSender response_sender, |
| 376 const std::vector<uint8_t>& value) { | 380 const std::vector<uint8_t>& value) { |
| 377 VLOG(2) << "Returning characteristic value obtained from delegate."; | 381 VLOG(2) << "Returning characteristic value obtained from delegate."; |
| 378 std::unique_ptr<dbus::Response> response = | 382 std::unique_ptr<dbus::Response> response = |
| 379 dbus::Response::FromMethodCall(method_call); | 383 dbus::Response::FromMethodCall(method_call); |
| 380 dbus::MessageWriter writer(response.get()); | 384 dbus::MessageWriter writer(response.get()); |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 400 void OnFailure(dbus::MethodCall* method_call, | 404 void OnFailure(dbus::MethodCall* method_call, |
| 401 dbus::ExportedObject::ResponseSender response_sender) { | 405 dbus::ExportedObject::ResponseSender response_sender) { |
| 402 VLOG(2) << "Failed to get/set characteristic value. Report error."; | 406 VLOG(2) << "Failed to get/set characteristic value. Report error."; |
| 403 std::unique_ptr<dbus::ErrorResponse> error_response = | 407 std::unique_ptr<dbus::ErrorResponse> error_response = |
| 404 dbus::ErrorResponse::FromMethodCall( | 408 dbus::ErrorResponse::FromMethodCall( |
| 405 method_call, kErrorFailed, | 409 method_call, kErrorFailed, |
| 406 "Failed to get/set characteristic value."); | 410 "Failed to get/set characteristic value."); |
| 407 response_sender.Run(std::move(error_response)); | 411 response_sender.Run(std::move(error_response)); |
| 408 } | 412 } |
| 409 | 413 |
| 414 const dbus::ObjectPath& object_path() const override { return object_path_; } | |
| 415 | |
| 410 // Origin thread (i.e. the UI thread in production). | 416 // Origin thread (i.e. the UI thread in production). |
| 411 base::PlatformThreadId origin_thread_id_; | 417 base::PlatformThreadId origin_thread_id_; |
| 412 | 418 |
| 413 // 128-bit characteristic UUID of this object. | 419 // 128-bit characteristic UUID of this object. |
| 414 std::string uuid_; | 420 std::string uuid_; |
| 415 | 421 |
| 416 // D-Bus bus object is exported on, not owned by this object and must | 422 // D-Bus bus object is exported on, not owned by this object and must |
| 417 // outlive it. | 423 // outlive it. |
| 418 dbus::Bus* bus_; | 424 dbus::Bus* bus_; |
| 419 | 425 |
| 420 // Incoming methods to get and set the "Value" property are passed on to the | 426 // Incoming methods to get and set the "Value" property are passed on to the |
| 421 // delegate and callbacks passed to generate a reply. |delegate_| is generally | 427 // delegate and callbacks passed to generate a reply. |delegate_| is generally |
| 422 // the object that owns this one and must outlive it. | 428 // the object that owns this one and must outlive it. |
| 423 Delegate* delegate_; | 429 std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate_; |
| 424 | 430 |
| 425 // D-Bus object path of object we are exporting, kept so we can unregister | 431 // D-Bus object path of object we are exporting, kept so we can unregister |
| 426 // again in our destructor. | 432 // again in our destructor. |
| 427 dbus::ObjectPath object_path_; | 433 dbus::ObjectPath object_path_; |
| 428 | 434 |
| 429 // Object path of the GATT service that the exported characteristic belongs | 435 // Object path of the GATT service that the exported characteristic belongs |
| 430 // to. | 436 // to. |
| 431 dbus::ObjectPath service_path_; | 437 dbus::ObjectPath service_path_; |
| 432 | 438 |
| 433 // D-Bus object we are exporting, owned by this object. | 439 // D-Bus object we are exporting, owned by this object. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 447 BluetoothGattCharacteristicServiceProvider() {} | 453 BluetoothGattCharacteristicServiceProvider() {} |
| 448 | 454 |
| 449 BluetoothGattCharacteristicServiceProvider:: | 455 BluetoothGattCharacteristicServiceProvider:: |
| 450 ~BluetoothGattCharacteristicServiceProvider() {} | 456 ~BluetoothGattCharacteristicServiceProvider() {} |
| 451 | 457 |
| 452 // static | 458 // static |
| 453 BluetoothGattCharacteristicServiceProvider* | 459 BluetoothGattCharacteristicServiceProvider* |
| 454 BluetoothGattCharacteristicServiceProvider::Create( | 460 BluetoothGattCharacteristicServiceProvider::Create( |
| 455 dbus::Bus* bus, | 461 dbus::Bus* bus, |
| 456 const dbus::ObjectPath& object_path, | 462 const dbus::ObjectPath& object_path, |
| 457 Delegate* delegate, | 463 std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate, |
| 458 const std::string& uuid, | 464 const std::string& uuid, |
| 459 const std::vector<std::string>& flags, | 465 const std::vector<std::string>& flags, |
| 460 const std::vector<std::string>& permissions, | 466 const std::vector<std::string>& permissions, |
| 461 const dbus::ObjectPath& service_path) { | 467 const dbus::ObjectPath& service_path) { |
| 462 if (!bluez::BluezDBusManager::Get()->IsUsingFakes()) { | 468 if (!bluez::BluezDBusManager::Get()->IsUsingFakes()) { |
| 463 return new BluetoothGattCharacteristicServiceProviderImpl( | 469 return new BluetoothGattCharacteristicServiceProviderImpl( |
| 464 bus, object_path, delegate, uuid, flags, permissions, service_path); | 470 bus, object_path, std::move(delegate), uuid, flags, permissions, |
| 471 service_path); | |
| 465 } | 472 } |
| 466 return new FakeBluetoothGattCharacteristicServiceProvider( | 473 return new FakeBluetoothGattCharacteristicServiceProvider( |
| 467 object_path, delegate, uuid, flags, permissions, service_path); | 474 object_path, std::move(delegate), uuid, flags, permissions, service_path); |
| 468 } | 475 } |
| 469 | 476 |
| 470 } // namespace bluez | 477 } // namespace bluez |
| OLD | NEW |