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..712584ff44df26259babce88276e781f05eb24ad 100644 |
--- a/device/bluetooth/dbus/bluetooth_adapter_client.cc |
+++ b/device/bluetooth/dbus/bluetooth_adapter_client.cc |
@@ -5,16 +5,44 @@ |
#include "device/bluetooth/dbus/bluetooth_adapter_client.h" |
#include "base/bind.h" |
+#include "base/callback.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.type()); |
+ struct_writer.AppendUint32(attribute.size()); |
+ |
+ if (attribute.type() != BluetoothServiceAttributeValueBlueZ::SEQUENCE) { |
+ dbus::AppendValueDataAsVariant(&struct_writer, attribute.value()); |
+ } else { |
+ dbus::MessageWriter array_writer(nullptr); |
+ struct_writer.OpenArray("v", &array_writer); |
+ for (const auto& v : attribute.sequence()) |
+ WriteAttribute(&array_writer, v); |
+ struct_writer.CloseContainer(&array_writer); |
+ } |
+ writer->CloseContainer(&struct_writer); |
+} |
+} |
+ |
BluetoothAdapterClient::DiscoveryFilter::DiscoveryFilter() {} |
BluetoothAdapterClient::DiscoveryFilter::~DiscoveryFilter() {} |
@@ -267,6 +295,64 @@ 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); |
+ const BluetoothServiceAttributeValueBlueZ& attribute_value = |
+ record.GetAttributeValue(attribute_id); |
+ WriteAttribute(&dict_entry_writer, attribute_value); |
+ } |
+ |
+ 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 +390,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(); |