device/bluetooth: Update GATT descriptor value D-Bus bindings.

This CL updates the Chrome D-Bus bindings and modifies the device/bluetooth
GATT Chrome OS code to use the new bindings defined in crbug.com/378182 for
descriptor value reads and writes.

BUG=378182
TEST=device_unittests; manual tests using custom bluetoothd

Review URL: https://codereview.chromium.org/309623002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275718 0039d316-1c4b-4281-b951-d872f2087c98
parent c9427af6
...@@ -13,6 +13,13 @@ ...@@ -13,6 +13,13 @@
namespace chromeos { namespace chromeos {
// static
const char BluetoothGattDescriptorClient::kNoResponseError[] =
"org.chromium.Error.NoResponse";
// static
const char BluetoothGattDescriptorClient::kUnknownDescriptorError[] =
"org.chromium.Error.UnknownDescriptor";
BluetoothGattDescriptorClient::Properties::Properties( BluetoothGattDescriptorClient::Properties::Properties(
dbus::ObjectProxy* object_proxy, dbus::ObjectProxy* object_proxy,
const std::string& interface_name, const std::string& interface_name,
...@@ -21,7 +28,6 @@ BluetoothGattDescriptorClient::Properties::Properties( ...@@ -21,7 +28,6 @@ BluetoothGattDescriptorClient::Properties::Properties(
RegisterProperty(bluetooth_gatt_descriptor::kUUIDProperty, &uuid); RegisterProperty(bluetooth_gatt_descriptor::kUUIDProperty, &uuid);
RegisterProperty(bluetooth_gatt_descriptor::kCharacteristicProperty, RegisterProperty(bluetooth_gatt_descriptor::kCharacteristicProperty,
&characteristic); &characteristic);
RegisterProperty(bluetooth_gatt_descriptor::kValueProperty, &value);
} }
BluetoothGattDescriptorClient::Properties::~Properties() { BluetoothGattDescriptorClient::Properties::~Properties() {
...@@ -73,6 +79,61 @@ class BluetoothGattDescriptorClientImpl ...@@ -73,6 +79,61 @@ class BluetoothGattDescriptorClientImpl
bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface)); bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface));
} }
// BluetoothGattDescriptorClientImpl override.
virtual void ReadValue(const dbus::ObjectPath& object_path,
const ValueCallback& callback,
const ErrorCallback& error_callback) OVERRIDE {
dbus::ObjectProxy* object_proxy =
object_manager_->GetObjectProxy(object_path);
if (!object_proxy) {
error_callback.Run(kUnknownDescriptorError, "");
return;
}
dbus::MethodCall method_call(
bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface,
bluetooth_gatt_descriptor::kReadValue);
object_proxy->CallMethodWithErrorCallback(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&BluetoothGattDescriptorClientImpl::OnValueSuccess,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&BluetoothGattDescriptorClientImpl::OnError,
weak_ptr_factory_.GetWeakPtr(),
error_callback));
}
// BluetoothGattDescriptorClientImpl override.
virtual void WriteValue(const dbus::ObjectPath& object_path,
const std::vector<uint8>& value,
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE {
dbus::ObjectProxy* object_proxy =
object_manager_->GetObjectProxy(object_path);
if (!object_proxy) {
error_callback.Run(kUnknownDescriptorError, "");
return;
}
dbus::MethodCall method_call(
bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface,
bluetooth_gatt_descriptor::kWriteValue);
dbus::MessageWriter writer(&method_call);
writer.AppendArrayOfBytes(value.data(), value.size());
object_proxy->CallMethodWithErrorCallback(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&BluetoothGattDescriptorClientImpl::OnSuccess,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&BluetoothGattDescriptorClientImpl::OnError,
weak_ptr_factory_.GetWeakPtr(),
error_callback));
}
// dbus::ObjectManager::Interface override. // dbus::ObjectManager::Interface override.
virtual dbus::PropertySet* CreateProperties( virtual dbus::PropertySet* CreateProperties(
dbus::ObjectProxy *object_proxy, dbus::ObjectProxy *object_proxy,
...@@ -128,6 +189,49 @@ class BluetoothGattDescriptorClientImpl ...@@ -128,6 +189,49 @@ class BluetoothGattDescriptorClientImpl
property_name)); property_name));
} }
// Called when a response for a successful method call is received.
void OnSuccess(const base::Closure& callback, dbus::Response* response) {
DCHECK(response);
callback.Run();
}
// Called when a descriptor value response for a successful method call is
// received.
void OnValueSuccess(const ValueCallback& callback, dbus::Response* response) {
DCHECK(response);
dbus::MessageReader reader(response);
const uint8* bytes = NULL;
size_t length = 0;
if (!reader.PopArrayOfBytes(&bytes, &length))
VLOG(2) << "Error reading array of bytes in ValueCallback";
std::vector<uint8> value;
if (bytes)
value.assign(bytes, bytes + length);
callback.Run(value);
}
// Called when a response for a failed method call is received.
void OnError(const ErrorCallback& error_callback,
dbus::ErrorResponse* response) {
// Error response has optional error message argument.
std::string error_name;
std::string error_message;
if (response) {
dbus::MessageReader reader(response);
error_name = response->GetErrorName();
reader.PopString(&error_message);
} else {
error_name = kNoResponseError;
error_message = "";
}
error_callback.Run(error_name, error_message);
}
dbus::ObjectManager* object_manager_; dbus::ObjectManager* object_manager_;
// List of observers interested in event notifications from us. // List of observers interested in event notifications from us.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/callback.h"
#include "chromeos/chromeos_export.h" #include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h" #include "chromeos/dbus/dbus_client.h"
#include "dbus/object_path.h" #include "dbus/object_path.h"
...@@ -28,11 +29,6 @@ class CHROMEOS_EXPORT BluetoothGattDescriptorClient : public DBusClient { ...@@ -28,11 +29,6 @@ class CHROMEOS_EXPORT BluetoothGattDescriptorClient : public DBusClient {
// [read-only] // [read-only]
dbus::Property<dbus::ObjectPath> characteristic; dbus::Property<dbus::ObjectPath> characteristic;
// Raw characteristic descriptor value read from the remote Bluetooth
// device. Setting the value sends a write request to the remote device.
// [read-write]
dbus::Property<std::vector<uint8> > value;
Properties(dbus::ObjectProxy* object_proxy, Properties(dbus::ObjectProxy* object_proxy,
const std::string& interface_name, const std::string& interface_name,
const PropertyChangedCallback& callback); const PropertyChangedCallback& callback);
...@@ -60,6 +56,11 @@ class CHROMEOS_EXPORT BluetoothGattDescriptorClient : public DBusClient { ...@@ -60,6 +56,11 @@ class CHROMEOS_EXPORT BluetoothGattDescriptorClient : public DBusClient {
const std::string& property_name) {} const std::string& property_name) {}
}; };
// Callbacks used to report the result of asynchronous methods.
typedef base::Callback<void(const std::string& error_name,
const std::string& error_message)> ErrorCallback;
typedef base::Callback<void(const std::vector<uint8>& value)> ValueCallback;
virtual ~BluetoothGattDescriptorClient(); virtual ~BluetoothGattDescriptorClient();
// Adds and removes observers for events on all remote GATT descriptors. Check // Adds and removes observers for events on all remote GATT descriptors. Check
...@@ -75,9 +76,28 @@ class CHROMEOS_EXPORT BluetoothGattDescriptorClient : public DBusClient { ...@@ -75,9 +76,28 @@ class CHROMEOS_EXPORT BluetoothGattDescriptorClient : public DBusClient {
// |object_path|. Values should be copied if needed. // |object_path|. Values should be copied if needed.
virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0; virtual Properties* GetProperties(const dbus::ObjectPath& object_path) = 0;
// Issues a request to read the value of GATT descriptor with object path
// |object_path| and returns the value in |callback| on success. On error,
// invokes |error_callback|.
virtual void ReadValue(const dbus::ObjectPath& object_path,
const ValueCallback& callback,
const ErrorCallback& error_callback) = 0;
// Issues a request to write the value of GATT descriptor with object path
// |object_path| with value |value|. Invokes |callback| on success and
// |error_callback| on failure.
virtual void WriteValue(const dbus::ObjectPath& object_path,
const std::vector<uint8>& value,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// Creates the instance. // Creates the instance.
static BluetoothGattDescriptorClient* Create(); static BluetoothGattDescriptorClient* Create();
// Constants used to indicate exceptional error conditions.
static const char kNoResponseError[];
static const char kUnknownDescriptorError[];
protected: protected:
BluetoothGattDescriptorClient(); BluetoothGattDescriptorClient();
......
...@@ -42,19 +42,13 @@ void FakeBluetoothGattDescriptorClient::Properties::Set( ...@@ -42,19 +42,13 @@ void FakeBluetoothGattDescriptorClient::Properties::Set(
dbus::PropertyBase* property, dbus::PropertyBase* property,
dbus::PropertySet::SetCallback callback) { dbus::PropertySet::SetCallback callback) {
VLOG(1) << "Set " << property->name(); VLOG(1) << "Set " << property->name();
if (property->name() != value.name()) { callback.Run(false);
callback.Run(false); }
return;
}
// TODO(armansito): Setting the "Value" property should be allowed based FakeBluetoothGattDescriptorClient::DescriptorData::DescriptorData() {
// on permissions. }
if (uuid.value() != kClientCharacteristicConfigurationUUID) {
callback.Run(false); FakeBluetoothGattDescriptorClient::DescriptorData::~DescriptorData() {
return;
}
callback.Run(true);
property->ReplaceValueWithSetValue();
} }
FakeBluetoothGattDescriptorClient::FakeBluetoothGattDescriptorClient() FakeBluetoothGattDescriptorClient::FakeBluetoothGattDescriptorClient()
...@@ -91,7 +85,37 @@ FakeBluetoothGattDescriptorClient::GetProperties( ...@@ -91,7 +85,37 @@ FakeBluetoothGattDescriptorClient::GetProperties(
PropertiesMap::const_iterator iter = properties_.find(object_path); PropertiesMap::const_iterator iter = properties_.find(object_path);
if (iter == properties_.end()) if (iter == properties_.end())
return NULL; return NULL;
return iter->second; return iter->second->properties.get();
}
void FakeBluetoothGattDescriptorClient::ReadValue(
const dbus::ObjectPath& object_path,
const ValueCallback& callback,
const ErrorCallback& error_callback) {
PropertiesMap::iterator iter = properties_.find(object_path);
if (iter == properties_.end()) {
error_callback.Run(kUnknownDescriptorError, "");
return;
}
callback.Run(iter->second->value);
}
void FakeBluetoothGattDescriptorClient::WriteValue(
const dbus::ObjectPath& object_path,
const std::vector<uint8>& value,
const base::Closure& callback,
const ErrorCallback& error_callback) {
if (properties_.find(object_path) == properties_.end()) {
error_callback.Run(kUnknownDescriptorError, "");
return;
}
// Since the only fake descriptor is "Client Characteristic Configuration"
// and BlueZ doesn't allow writing to it, return failure.
error_callback.Run("org.bluez.Error.Failed",
"Writing to the Client Characteristic Configuration "
"descriptor not allowed");
} }
dbus::ObjectPath FakeBluetoothGattDescriptorClient::ExposeDescriptor( dbus::ObjectPath FakeBluetoothGattDescriptorClient::ExposeDescriptor(
...@@ -118,14 +142,16 @@ dbus::ObjectPath FakeBluetoothGattDescriptorClient::ExposeDescriptor( ...@@ -118,14 +142,16 @@ dbus::ObjectPath FakeBluetoothGattDescriptorClient::ExposeDescriptor(
&FakeBluetoothGattDescriptorClient::OnPropertyChanged, &FakeBluetoothGattDescriptorClient::OnPropertyChanged,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
object_path)); object_path));
properties_[object_path] = properties;
properties->uuid.ReplaceValue(uuid); properties->uuid.ReplaceValue(uuid);
properties->characteristic.ReplaceValue(characteristic_path); properties->characteristic.ReplaceValue(characteristic_path);
std::vector<uint8> value; DescriptorData* data = new DescriptorData();
value.push_back(0); // Notifications/Indications disabled. data->properties.reset(properties);
value.push_back(0);
properties->value.ReplaceValue(value); data->value.push_back(1); // Notifications enabled.
data->value.push_back(0);
properties_[object_path] = data;
NotifyDescriptorAdded(object_path); NotifyDescriptorAdded(object_path);
...@@ -154,9 +180,6 @@ void FakeBluetoothGattDescriptorClient::OnPropertyChanged( ...@@ -154,9 +180,6 @@ void FakeBluetoothGattDescriptorClient::OnPropertyChanged(
FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_, FOR_EACH_OBSERVER(BluetoothGattDescriptorClient::Observer, observers_,
GattDescriptorPropertyChanged(object_path, property_name)); GattDescriptorPropertyChanged(object_path, property_name));
// TODO(armansito): Implement CCC behavior (enable/disable notifications
// or indications characteristics).
} }
void FakeBluetoothGattDescriptorClient::NotifyDescriptorAdded( void FakeBluetoothGattDescriptorClient::NotifyDescriptorAdded(
......
...@@ -46,6 +46,13 @@ class CHROMEOS_EXPORT FakeBluetoothGattDescriptorClient ...@@ -46,6 +46,13 @@ class CHROMEOS_EXPORT FakeBluetoothGattDescriptorClient
virtual std::vector<dbus::ObjectPath> GetDescriptors() OVERRIDE; virtual std::vector<dbus::ObjectPath> GetDescriptors() OVERRIDE;
virtual Properties* GetProperties(const dbus::ObjectPath& object_path) virtual Properties* GetProperties(const dbus::ObjectPath& object_path)
OVERRIDE; OVERRIDE;
virtual void ReadValue(const dbus::ObjectPath& object_path,
const ValueCallback& callback,
const ErrorCallback& error_callback) OVERRIDE;
virtual void WriteValue(const dbus::ObjectPath& object_path,
const std::vector<uint8>& value,
const base::Closure& callback,
const ErrorCallback& error_callback) OVERRIDE;
// Makes the descriptor with the UUID |uuid| visible under the characteristic // Makes the descriptor with the UUID |uuid| visible under the characteristic
// with object path |characteristic_path|. Descriptor object paths are // with object path |characteristic_path|. Descriptor object paths are
...@@ -71,7 +78,14 @@ class CHROMEOS_EXPORT FakeBluetoothGattDescriptorClient ...@@ -71,7 +78,14 @@ class CHROMEOS_EXPORT FakeBluetoothGattDescriptorClient
void NotifyDescriptorRemoved(const dbus::ObjectPath& object_path); void NotifyDescriptorRemoved(const dbus::ObjectPath& object_path);
// Mapping from object paths to Properties structures. // Mapping from object paths to Properties structures.
typedef std::map<dbus::ObjectPath, Properties*> PropertiesMap; struct DescriptorData {
DescriptorData();
~DescriptorData();
scoped_ptr<Properties> properties;
std::vector<uint8> value;
};
typedef std::map<dbus::ObjectPath, DescriptorData*> PropertiesMap;
PropertiesMap properties_; PropertiesMap properties_;
// List of observers interested in event notifications from us. // List of observers interested in event notifications from us.
......
...@@ -944,15 +944,19 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) { ...@@ -944,15 +944,19 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
descriptor->GetUUID()); descriptor->GetUUID());
std::vector<uint8> desc_value; std::vector<uint8> desc_value;
desc_value.push_back(1);
desc_value.push_back(0); desc_value.push_back(0);
desc_value.push_back(0);
EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue())); /* The cached value will be empty until the first read request */
EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
EXPECT_TRUE(descriptor->GetValue().empty());
EXPECT_EQ(0, success_callback_count_); EXPECT_EQ(0, success_callback_count_);
EXPECT_EQ(0, error_callback_count_); EXPECT_EQ(0, error_callback_count_);
EXPECT_TRUE(last_read_value_.empty()); EXPECT_TRUE(last_read_value_.empty());
// Read value. // Read value. GattDescriptorValueChanged event will be sent after a
// successful read.
descriptor->ReadRemoteDescriptor( descriptor->ReadRemoteDescriptor(
base::Bind(&BluetoothGattChromeOSTest::ValueCallback, base::Bind(&BluetoothGattChromeOSTest::ValueCallback,
base::Unretained(this)), base::Unretained(this)),
...@@ -961,10 +965,11 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) { ...@@ -961,10 +965,11 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
EXPECT_EQ(1, success_callback_count_); EXPECT_EQ(1, success_callback_count_);
EXPECT_EQ(0, error_callback_count_); EXPECT_EQ(0, error_callback_count_);
EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue())); EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue()));
EXPECT_EQ(4, service_observer.gatt_service_changed_count_); EXPECT_EQ(4, service_observer.gatt_service_changed_count_);
EXPECT_EQ(0, service_observer.gatt_descriptor_value_changed_count_); EXPECT_EQ(1, service_observer.gatt_descriptor_value_changed_count_);
// Write value. // Write value. Writes to this descriptor will fail.
desc_value[0] = 0x03; desc_value[0] = 0x03;
descriptor->WriteRemoteDescriptor( descriptor->WriteRemoteDescriptor(
desc_value, desc_value,
...@@ -972,10 +977,10 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) { ...@@ -972,10 +977,10 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
base::Unretained(this)), base::Unretained(this)),
base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, base::Bind(&BluetoothGattChromeOSTest::ErrorCallback,
base::Unretained(this))); base::Unretained(this)));
EXPECT_EQ(2, success_callback_count_); EXPECT_EQ(1, success_callback_count_);
EXPECT_EQ(0, error_callback_count_); EXPECT_EQ(1, error_callback_count_);
EXPECT_FALSE(ValuesEqual(last_read_value_, descriptor->GetValue())); EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue())); EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
EXPECT_EQ(4, service_observer.gatt_service_changed_count_); EXPECT_EQ(4, service_observer.gatt_service_changed_count_);
EXPECT_EQ(1, service_observer.gatt_descriptor_value_changed_count_); EXPECT_EQ(1, service_observer.gatt_descriptor_value_changed_count_);
...@@ -985,12 +990,12 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) { ...@@ -985,12 +990,12 @@ TEST_F(BluetoothGattChromeOSTest, GattDescriptorValue) {
base::Unretained(this)), base::Unretained(this)),
base::Bind(&BluetoothGattChromeOSTest::ErrorCallback, base::Bind(&BluetoothGattChromeOSTest::ErrorCallback,
base::Unretained(this))); base::Unretained(this)));
EXPECT_EQ(3, success_callback_count_); EXPECT_EQ(2, success_callback_count_);
EXPECT_EQ(0, error_callback_count_); EXPECT_EQ(1, error_callback_count_);
EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue())); EXPECT_TRUE(ValuesEqual(last_read_value_, descriptor->GetValue()));
EXPECT_TRUE(ValuesEqual(desc_value, descriptor->GetValue())); EXPECT_FALSE(ValuesEqual(desc_value, descriptor->GetValue()));
EXPECT_EQ(4, service_observer.gatt_service_changed_count_); EXPECT_EQ(4, service_observer.gatt_service_changed_count_);
EXPECT_EQ(1, service_observer.gatt_descriptor_value_changed_count_); EXPECT_EQ(2, service_observer.gatt_descriptor_value_changed_count_);
} }
} // namespace chromeos } // namespace chromeos
...@@ -268,30 +268,6 @@ void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorRemoved( ...@@ -268,30 +268,6 @@ void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorRemoved(
service_->NotifyServiceChanged(); service_->NotifyServiceChanged();
} }
void BluetoothRemoteGattCharacteristicChromeOS::GattDescriptorPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
DescriptorMap::const_iterator iter = descriptors_.find(object_path);
if (iter == descriptors_.end())
return;
// Ignore all property changes except for "Value".
BluetoothGattDescriptorClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
GetProperties(object_path);
DCHECK(properties);
if (property_name != properties->value.name())
return;
VLOG(1) << "GATT descriptor property changed: " << object_path.value()
<< ", property: " << property_name;
DCHECK(service_);
service_->NotifyDescriptorValueChanged(
this, iter->second, properties->value.value());
}
void BluetoothRemoteGattCharacteristicChromeOS::OnValueSuccess( void BluetoothRemoteGattCharacteristicChromeOS::OnValueSuccess(
const ValueCallback& callback, const ValueCallback& callback,
const std::vector<uint8>& value) { const std::vector<uint8>& value) {
......
...@@ -80,9 +80,6 @@ class BluetoothRemoteGattCharacteristicChromeOS ...@@ -80,9 +80,6 @@ class BluetoothRemoteGattCharacteristicChromeOS
const dbus::ObjectPath& object_path) OVERRIDE; const dbus::ObjectPath& object_path) OVERRIDE;
virtual void GattDescriptorRemoved( virtual void GattDescriptorRemoved(
const dbus::ObjectPath& object_path) OVERRIDE; const dbus::ObjectPath& object_path) OVERRIDE;
virtual void GattDescriptorPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) OVERRIDE;
// Called by dbus:: on successful completion of a request to read // Called by dbus:: on successful completion of a request to read
// the characteristic value. // the characteristic value.
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "chromeos/dbus/bluetooth_gatt_descriptor_client.h" #include "chromeos/dbus/bluetooth_gatt_descriptor_client.h"
#include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/dbus_thread_manager.h"
#include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h" #include "device/bluetooth/bluetooth_remote_gatt_characteristic_chromeos.h"
#include "device/bluetooth/bluetooth_remote_gatt_service_chromeos.h"
namespace chromeos { namespace chromeos {
...@@ -59,11 +60,7 @@ bool BluetoothRemoteGattDescriptorChromeOS::IsLocal() const { ...@@ -59,11 +60,7 @@ bool BluetoothRemoteGattDescriptorChromeOS::IsLocal() const {
const std::vector<uint8>& const std::vector<uint8>&
BluetoothRemoteGattDescriptorChromeOS::GetValue() const { BluetoothRemoteGattDescriptorChromeOS::GetValue() const {
BluetoothGattDescriptorClient::Properties* properties = return cached_value_;
DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->
GetProperties(object_path_);
DCHECK(properties);
return properties->value.value();
} }
device::BluetoothGattCharacteristic* device::BluetoothGattCharacteristic*
...@@ -84,14 +81,15 @@ void BluetoothRemoteGattDescriptorChromeOS::ReadRemoteDescriptor( ...@@ -84,14 +81,15 @@ void BluetoothRemoteGattDescriptorChromeOS::ReadRemoteDescriptor(
VLOG(1) << "Sending GATT characteristic descriptor read request to " VLOG(1) << "Sending GATT characteristic descriptor read request to "
<< "descriptor: " << GetIdentifier() << ", UUID: " << "descriptor: " << GetIdentifier() << ", UUID: "
<< GetUUID().canonical_value(); << GetUUID().canonical_value();
BluetoothGattDescriptorClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()-> DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->ReadValue(
GetProperties(object_path_); object_path_,
DCHECK(properties); base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnValueSuccess,
properties->value.Get( weak_ptr_factory_.GetWeakPtr(),
base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnGetValue, callback),
base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
callback, error_callback)); error_callback));
} }
void BluetoothRemoteGattDescriptorChromeOS::WriteRemoteDescriptor( void BluetoothRemoteGattDescriptorChromeOS::WriteRemoteDescriptor(
...@@ -102,47 +100,38 @@ void BluetoothRemoteGattDescriptorChromeOS::WriteRemoteDescriptor( ...@@ -102,47 +100,38 @@ void BluetoothRemoteGattDescriptorChromeOS::WriteRemoteDescriptor(
<< "characteristic: " << GetIdentifier() << ", UUID: " << "characteristic: " << GetIdentifier() << ", UUID: "
<< GetUUID().canonical_value() << ", with value: " << GetUUID().canonical_value() << ", with value: "
<< new_value << "."; << new_value << ".";
BluetoothGattDescriptorClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()-> DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()->WriteValue(
GetProperties(object_path_); object_path_,
DCHECK(properties);
properties->value.Set(
new_value, new_value,
base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnSetValue, callback,
base::Bind(&BluetoothRemoteGattDescriptorChromeOS::OnError,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
callback, error_callback)); error_callback));
} }
void BluetoothRemoteGattDescriptorChromeOS::OnGetValue( void BluetoothRemoteGattDescriptorChromeOS::OnValueSuccess(
const ValueCallback& callback, const ValueCallback& callback,
const ErrorCallback& error_callback, const std::vector<uint8>& value) {
bool success) { VLOG(1) << "Descriptor value read: " << value;
if (!success) { cached_value_ = value;
VLOG(1) << "Failed to read the value from the remote descriptor.";
error_callback.Run(); DCHECK(characteristic_);
return; BluetoothRemoteGattServiceChromeOS* service =
} static_cast<BluetoothRemoteGattServiceChromeOS*>(
characteristic_->GetService());
VLOG(1) << "Read value of remote descriptor."; DCHECK(service);
BluetoothGattDescriptorClient::Properties* properties = service->NotifyDescriptorValueChanged(characteristic_, this, value);
DBusThreadManager::Get()->GetBluetoothGattDescriptorClient()-> callback.Run(value);
GetProperties(object_path_);
DCHECK(properties);
callback.Run(properties->value.value());
} }
void BluetoothRemoteGattDescriptorChromeOS::OnSetValue( void BluetoothRemoteGattDescriptorChromeOS::OnError(
const base::Closure& callback,
const ErrorCallback& error_callback, const ErrorCallback& error_callback,
bool success) { const std::string& error_name,
if (!success) { const std::string& error_message) {
VLOG(1) << "Failed to write the value of remote descriptor."; VLOG(1) << "Operation failed: " << error_name
error_callback.Run(); << ", message: " << error_message;
return; error_callback.Run();
}
VLOG(1) << "Wrote value of remote descriptor.";
callback.Run();
} }
} // namespace chromeos } // namespace chromeos
...@@ -57,15 +57,16 @@ class BluetoothRemoteGattDescriptorChromeOS ...@@ -57,15 +57,16 @@ class BluetoothRemoteGattDescriptorChromeOS
const dbus::ObjectPath& object_path); const dbus::ObjectPath& object_path);
virtual ~BluetoothRemoteGattDescriptorChromeOS(); virtual ~BluetoothRemoteGattDescriptorChromeOS();
// Called by dbus:: on completion of the request to get the descriptor value. // Called by dbus:: on successful completion of a request to read
void OnGetValue(const ValueCallback& callback, // the descriptor value.
const ErrorCallback& error_callback, void OnValueSuccess(const ValueCallback& callback,
bool success); const std::vector<uint8>& value);
// Called by dbus:: on completion of the request to set the descriptor value. // Called by dbus:: on unsuccessful completion of a request to read or write
void OnSetValue(const base::Closure& callback, // the descriptor value.
const ErrorCallback& error_callback, void OnError(const ErrorCallback& error_callback,
bool success); const std::string& error_name,
const std::string& error_message);
// Object path of the D-Bus descriptor object. // Object path of the D-Bus descriptor object.
dbus::ObjectPath object_path_; dbus::ObjectPath object_path_;
...@@ -73,6 +74,9 @@ class BluetoothRemoteGattDescriptorChromeOS ...@@ -73,6 +74,9 @@ class BluetoothRemoteGattDescriptorChromeOS
// The GATT characteristic this descriptor belongs to. // The GATT characteristic this descriptor belongs to.
BluetoothRemoteGattCharacteristicChromeOS* characteristic_; BluetoothRemoteGattCharacteristicChromeOS* characteristic_;
// The cached characteristic value based on the most recent read request.
std::vector<uint8> cached_value_;
// Note: This should remain the last member so it'll be destroyed and // Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed. // invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<BluetoothRemoteGattDescriptorChromeOS> weak_ptr_factory_; base::WeakPtrFactory<BluetoothRemoteGattDescriptorChromeOS> weak_ptr_factory_;
......
...@@ -89,8 +89,8 @@ class BluetoothRemoteGattServiceChromeOS ...@@ -89,8 +89,8 @@ class BluetoothRemoteGattServiceChromeOS
bool added); bool added);
// Notifies its observers that the value of a descriptor has changed. Called // Notifies its observers that the value of a descriptor has changed. Called
// by BluetoothRemoteGattCharacteristicChromeOS instances to notify service // by BluetoothRemoteGattDescriptorChromeOS instances to notify service
// observers when the value of one of their descriptors gets updated. // observers when their cached value gets updated after a read request.
void NotifyDescriptorValueChanged( void NotifyDescriptorValueChanged(
BluetoothRemoteGattCharacteristicChromeOS* characteristic, BluetoothRemoteGattCharacteristicChromeOS* characteristic,
BluetoothRemoteGattDescriptorChromeOS* descriptor, BluetoothRemoteGattDescriptorChromeOS* descriptor,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment