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