Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(280)

Unified Diff: device/bluetooth/dbus/bluetooth_device_client.cc

Issue 2102093003: Implement BluetoothDeviceBlueZ::GetServiceRecords. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: device/bluetooth/dbus/bluetooth_device_client.cc
diff --git a/device/bluetooth/dbus/bluetooth_device_client.cc b/device/bluetooth/dbus/bluetooth_device_client.cc
index 920fb3c9c82ab13a2357bad9c9bad3892a9e3a7f..a081b658363f744f355f0a8111fe2bfe7491e966 100644
--- a/device/bluetooth/dbus/bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/bluetooth_device_client.cc
@@ -7,11 +7,13 @@
#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_manager.h"
#include "dbus/object_proxy.h"
+#include "device/bluetooth/bluez/bluetooth_service_attribute_value_bluez.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace bluez {
@@ -21,6 +23,150 @@ namespace {
// Value returned for the the RSSI or TX power if it cannot be read.
const int kUnknownPower = 127;
+std::unique_ptr<BluetoothServiceAttributeValueBlueZ> ReadAttributeValue(
+ dbus::MessageReader* struct_reader) {
+ uint8_t type_val;
+ if (!struct_reader->PopByte(&type_val))
+ return nullptr;
+ BluetoothServiceAttributeValueBlueZ::Type type =
+ static_cast<BluetoothServiceAttributeValueBlueZ::Type>(type_val);
+
+ uint32_t size;
+ if (!struct_reader->PopUint32(&size))
+ return nullptr;
+
+ std::unique_ptr<base::Value> value = nullptr;
+ switch (type) {
+ case bluez::BluetoothServiceAttributeValueBlueZ::NULLTYPE: {
+ break;
+ }
+ case bluez::BluetoothServiceAttributeValueBlueZ::UINT:
+ // Fall through.
+ case bluez::BluetoothServiceAttributeValueBlueZ::INT: {
+ switch (size) {
+ // It doesn't matter what 'sign' the number is, only size.
+ // Whenever we unpack this value, we will take the raw bits and
+ // cast it back to the correct sign anyway.
+ case 1:
+ uint8_t byte;
+ if (!struct_reader->PopVariantOfByte(&byte))
+ return nullptr;
+ value = base::MakeUnique<base::FundamentalValue>(byte);
+ break;
+ case 2:
+ uint16_t short_val;
+ if (!struct_reader->PopVariantOfUint16(&short_val))
+ return nullptr;
+ value = base::MakeUnique<base::FundamentalValue>(short_val);
+ break;
+ case 4:
+ uint32_t val;
+ if (!struct_reader->PopVariantOfUint32(&val))
+ return nullptr;
+ value = base::MakeUnique<base::FundamentalValue>(
+ static_cast<int32_t>(val));
+ break;
+ case 8:
+ // Fall through.
+ // BlueZ should never be sending us this size at the moment since
+ // the Android SDP records we will create from these raw records
+ // don't have any fields which use this size. If we ever decide to
+ // change this, this needs to get fixed.
+ default:
+ NOTREACHED();
+ }
+ break;
+ }
+ case bluez::BluetoothServiceAttributeValueBlueZ::UUID:
+ // Fall through.
+ case bluez::BluetoothServiceAttributeValueBlueZ::STRING:
+ // Fall through.
+ case bluez::BluetoothServiceAttributeValueBlueZ::URL: {
+ std::string str;
+ if (!struct_reader->PopVariantOfString(&str))
+ return nullptr;
+ value = base::MakeUnique<base::StringValue>(str);
+ break;
+ }
+ case bluez::BluetoothServiceAttributeValueBlueZ::BOOL: {
+ bool b;
+ if (!struct_reader->PopVariantOfBool(&b))
+ return nullptr;
+ value = base::MakeUnique<base::FundamentalValue>(b);
+ break;
+ }
+ case bluez::BluetoothServiceAttributeValueBlueZ::SEQUENCE: {
+ dbus::MessageReader variant_reader(nullptr);
+ if (!struct_reader->PopVariant(&variant_reader))
+ return nullptr;
+ dbus::MessageReader array_reader(nullptr);
+ if (!variant_reader.PopArray(&array_reader))
+ return nullptr;
+ std::unique_ptr<BluetoothServiceAttributeValueBlueZ::Sequence> sequence =
+ base::MakeUnique<BluetoothServiceAttributeValueBlueZ::Sequence>();
+ while (array_reader.HasMoreData()) {
+ dbus::MessageReader sequence_element_struct_reader(nullptr);
+ if (!array_reader.PopStruct(&sequence_element_struct_reader))
+ return nullptr;
+ std::unique_ptr<BluetoothServiceAttributeValueBlueZ> attribute_value =
+ ReadAttributeValue(&sequence_element_struct_reader);
+ if (!attribute_value)
+ return nullptr;
+ sequence->emplace_back(*attribute_value);
+ }
+ return base::MakeUnique<BluetoothServiceAttributeValueBlueZ>(
+ std::move(sequence));
+ break;
xiyuan 2016/06/29 22:43:08 nit: no "break" since we "return" ?
rkc 2016/06/30 20:02:24 Done.
+ }
+ }
+ return base::MakeUnique<BluetoothServiceAttributeValueBlueZ>(
+ type, size, std::move(value));
+}
+
+std::unique_ptr<BluetoothServiceRecordBlueZ> ReadRecord(
+ dbus::MessageReader* array_reader) {
+ std::unique_ptr<BluetoothServiceRecordBlueZ> record =
+ base::MakeUnique<BluetoothServiceRecordBlueZ>();
+ while (array_reader->HasMoreData()) {
+ dbus::MessageReader dict_entry_reader(nullptr);
+ if (!array_reader->PopDictEntry(&dict_entry_reader))
+ return nullptr;
+ uint16_t id;
+ if (!dict_entry_reader.PopUint16(&id))
+ return nullptr;
+ dbus::MessageReader struct_reader(nullptr);
+ if (!dict_entry_reader.PopStruct(&struct_reader))
+ return nullptr;
+ std::unique_ptr<BluetoothServiceAttributeValueBlueZ> attribute_value =
+ ReadAttributeValue(&struct_reader);
+ if (!attribute_value)
+ return nullptr;
+ record->AddRecordEntry(id, *attribute_value);
+ }
+ // return std::move(record);
+ return record;
+}
+
+bool ReadRecordsFromMessage(dbus::MessageReader* reader,
+ BluetoothDeviceClient::ServiceRecordList* records) {
+ dbus::MessageReader array_reader(nullptr);
+ if (!reader->PopArray(&array_reader)) {
+ return false;
+ LOG(ERROR) << "Arguments for GetConnInfo invalid.";
+ }
+ while (array_reader.HasMoreData()) {
+ dbus::MessageReader nested_array_reader(nullptr);
+ if (!array_reader.PopArray(&nested_array_reader))
+ return false;
+ std::unique_ptr<BluetoothServiceRecordBlueZ> record =
+ ReadRecord(&nested_array_reader);
+ if (!record)
+ return false;
+ records->emplace_back(*record);
+ }
+ return true;
+}
+
} // namespace
const char BluetoothDeviceClient::kNoResponseError[] =
@@ -281,6 +427,26 @@ class BluetoothDeviceClientImpl : public BluetoothDeviceClient,
weak_ptr_factory_.GetWeakPtr(), error_callback));
}
+ void GetServiceRecords(const dbus::ObjectPath& object_path,
+ const ServiceRecordsCallback& callback,
+ const ErrorCallback& error_callback) override {
+ dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
+ bluetooth_device::kGetServiceRecords);
+
+ dbus::ObjectProxy* object_proxy =
+ object_manager_->GetObjectProxy(object_path);
+ if (!object_proxy) {
+ error_callback.Run(kUnknownDeviceError, "");
+ return;
+ }
+ object_proxy->CallMethodWithErrorCallback(
+ &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&BluetoothDeviceClientImpl::OnGetServiceRecordsSuccess,
+ weak_ptr_factory_.GetWeakPtr(), callback),
+ base::Bind(&BluetoothDeviceClientImpl::OnError,
+ weak_ptr_factory_.GetWeakPtr(), error_callback));
+ }
+
protected:
void Init(dbus::Bus* bus) override {
object_manager_ = bus->GetObjectManager(
@@ -344,6 +510,23 @@ class BluetoothDeviceClientImpl : public BluetoothDeviceClient,
callback.Run(rssi, transmit_power, max_transmit_power);
}
+ void OnGetServiceRecordsSuccess(const ServiceRecordsCallback& callback,
+ dbus::Response* response) {
+ ServiceRecordList records;
+ if (!response) {
+ LOG(ERROR) << "GetServiceRecords succeeded, but no response received.";
+ callback.Run(records);
+ return;
+ }
+
+ dbus::MessageReader reader(response);
+ if (!ReadRecordsFromMessage(&reader, &records)) {
+ callback.Run(ServiceRecordList());
+ }
+
+ callback.Run(records);
+ }
+
// Called when a response for a failed method call is received.
void OnError(const ErrorCallback& error_callback,
dbus::ErrorResponse* response) {

Powered by Google App Engine
This is Rietveld 408576698