Index: device/bluetooth/dbus/bluetooth_adapter_client.cc |
diff --git a/device/bluetooth/dbus/bluetooth_adapter_client.cc b/device/bluetooth/dbus/bluetooth_adapter_client.cc |
index e4eb8c126dd424ec74e0f7d2e2f80909b1cdd719..ac053fbe7d6f50aa8394fdb9b18626338feb76ab 100644 |
--- a/device/bluetooth/dbus/bluetooth_adapter_client.cc |
+++ b/device/bluetooth/dbus/bluetooth_adapter_client.cc |
@@ -6,15 +6,43 @@ |
#include "base/bind.h" |
#include "base/logging.h" |
-#include "base/macros.h" |
+#include "base/memory/weak_ptr.h" |
+#include "base/observer_list.h" |
+#include "base/values.h" |
#include "dbus/bus.h" |
#include "dbus/message.h" |
#include "dbus/object_manager.h" |
-#include "dbus/object_proxy.h" |
+#include "dbus/values_util.h" |
+#include "device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.h" |
+#include "device/bluetooth/bluez/bluetooth_service_record_bluez.h" |
#include "third_party/cros_system_api/dbus/service_constants.h" |
namespace bluez { |
+namespace { |
+ |
+void WriteAttribute(dbus::MessageWriter* writer, |
+ const BluetoothServiceAttributeValueBlueZ& attribute) { |
+ dbus::MessageWriter struct_writer(nullptr); |
+ writer->OpenStruct(&struct_writer); |
+ struct_writer.AppendByte(attribute.get_type()); |
+ struct_writer.AppendUint32(attribute.get_size()); |
+ |
+ if (attribute.get_type() != BluetoothServiceAttributeValueBlueZ::SEQUENCE) { |
+ CHECK(attribute.get_value().value); |
+ dbus::AppendValueDataAsVariant(&struct_writer, |
+ *attribute.get_value().value); |
+ } else { |
+ dbus::MessageWriter array_writer(nullptr); |
+ struct_writer.OpenArray("v", &array_writer); |
+ for (const auto& v : *attribute.get_value().sequence) |
+ WriteAttribute(&array_writer, v); |
+ struct_writer.CloseContainer(&array_writer); |
+ } |
+ writer->CloseContainer(&struct_writer); |
+} |
+} |
+ |
BluetoothAdapterClient::DiscoveryFilter::DiscoveryFilter() {} |
BluetoothAdapterClient::DiscoveryFilter::~DiscoveryFilter() {} |
@@ -267,6 +295,66 @@ class BluetoothAdapterClientImpl : public BluetoothAdapterClient, |
weak_ptr_factory_.GetWeakPtr(), error_callback)); |
} |
+ // BluetoothAdapterClient override. |
+ void CreateServiceRecord(const dbus::ObjectPath& object_path, |
+ const bluez::BluetoothServiceRecordBlueZ& record, |
+ const ServiceRecordCallback& callback, |
+ const ErrorCallback& error_callback) override { |
+ dbus::MethodCall method_call(bluetooth_adapter::kBluetoothAdapterInterface, |
+ bluetooth_adapter::kCreateServiceRecord); |
+ |
+ dbus::MessageWriter writer(&method_call); |
+ dbus::MessageWriter dict_entry_writer(nullptr); |
+ for (auto attribute_id : record.GetAttributeIds()) { |
+ writer.OpenDictEntry(&dict_entry_writer); |
+ dict_entry_writer.AppendUint16(attribute_id); |
+ BluetoothServiceAttributeValueBlueZ::ValueType value; |
+ value.value = nullptr; |
+ const BluetoothServiceAttributeValueBlueZ& attribute = |
+ record.GetAttributeValue(attribute_id); |
+ WriteAttribute(&dict_entry_writer, attribute); |
+ } |
+ |
+ dbus::ObjectProxy* object_proxy = |
+ object_manager_->GetObjectProxy(object_path); |
+ if (!object_proxy) { |
+ error_callback.Run(kUnknownAdapterError, ""); |
+ return; |
+ } |
+ |
+ object_proxy->CallMethodWithErrorCallback( |
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
+ base::Bind(&BluetoothAdapterClientImpl::OnCreateServiceRecord, |
+ weak_ptr_factory_.GetWeakPtr(), callback), |
+ base::Bind(&BluetoothAdapterClientImpl::OnError, |
+ weak_ptr_factory_.GetWeakPtr(), error_callback)); |
+ } |
+ |
+ // BluetoothAdapterClient override. |
+ void RemoveServiceRecord(const dbus::ObjectPath& object_path, |
+ uint32_t handle, |
+ const base::Closure& callback, |
+ const ErrorCallback& error_callback) override { |
+ dbus::MethodCall method_call(bluetooth_adapter::kBluetoothAdapterInterface, |
+ bluetooth_adapter::kRemoveServiceRecord); |
+ |
+ dbus::MessageWriter writer(&method_call); |
+ writer.AppendUint32(handle); |
+ dbus::ObjectProxy* object_proxy = |
+ object_manager_->GetObjectProxy(object_path); |
+ if (!object_proxy) { |
+ error_callback.Run(kUnknownAdapterError, ""); |
+ return; |
+ } |
+ |
+ object_proxy->CallMethodWithErrorCallback( |
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
+ base::Bind(&BluetoothAdapterClientImpl::OnSuccess, |
+ weak_ptr_factory_.GetWeakPtr(), callback), |
+ base::Bind(&BluetoothAdapterClientImpl::OnError, |
+ weak_ptr_factory_.GetWeakPtr(), error_callback)); |
+ } |
+ |
protected: |
void Init(dbus::Bus* bus) override { |
object_manager_ = bus->GetObjectManager( |
@@ -304,6 +392,17 @@ class BluetoothAdapterClientImpl : public BluetoothAdapterClient, |
} |
// Called when a response for successful method call is received. |
+ void OnCreateServiceRecord(const ServiceRecordCallback& callback, |
+ dbus::Response* response) { |
+ DCHECK(response); |
+ dbus::MessageReader reader(response); |
+ uint32_t handle = 0; |
+ if (!reader.PopUint32(&handle)) |
+ LOG(ERROR) << "Invalid response from CreateServiceRecord."; |
+ callback.Run(handle); |
+ } |
+ |
+ // Called when a response for successful method call is received. |
void OnSuccess(const base::Closure& callback, dbus::Response* response) { |
DCHECK(response); |
callback.Run(); |