Commit 18bc783f authored by David Lechner's avatar David Lechner Committed by Commit Bot

bluetooth: implement new WriteRemoteCharacteristic

After deprecating the previous implementation, we need to create a new
implementation that allows selecting write with or without response.

The new implementation is simply a copy of the deprecated implementation
with the following changes:

- An enum WriteType parameter is added to select with or without
  response.
- All GATT characteristic property checks are removed and the new enum
  parameter is used to select the write type instead.
- Additional write flags parameters are added to the platform-specific
  backends as needed.
  - For most platforms, these are just bit flags/enums.
  - For BlueZ, this is a string.
  - On the "win" backend, the part that depends on the characteristic
    property was moved to the DeprecatedWriteRemoteCharacteristic
    method since it would otherwise interfere with the new
    implementation.
  - On the "cast" backend, we are able to use the existing WriteAuth
    method without additional modification.

Likewise, the new unit tests are just a copy of the same unit tests that
call the DeprecatedWriteRemoteCharacteristic method. The new tests have
been modified to try to avoid using base::RunLoop::RunUntilIdle.

Bug: 672648
Change-Id: I7958d9e6d3fd285695091fe3220b3d2fce45c641
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2191232
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarVincent Scheib <scheib@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#769949}
parent 26d4e3ec
...@@ -130,11 +130,14 @@ final class ChromeBluetoothRemoteGattCharacteristic { ...@@ -130,11 +130,14 @@ final class ChromeBluetoothRemoteGattCharacteristic {
// Implements BluetoothRemoteGattCharacteristicAndroid::WriteRemoteCharacteristic. // Implements BluetoothRemoteGattCharacteristicAndroid::WriteRemoteCharacteristic.
@CalledByNative @CalledByNative
private boolean writeRemoteCharacteristic(byte[] value) { private boolean writeRemoteCharacteristic(byte[] value, int writeType) {
if (!mCharacteristic.setValue(value)) { if (!mCharacteristic.setValue(value)) {
Log.i(TAG, "writeRemoteCharacteristic setValue failed."); Log.i(TAG, "writeRemoteCharacteristic setValue failed.");
return false; return false;
} }
if (writeType != 0) {
mCharacteristic.setWriteType(writeType);
}
if (!mChromeDevice.mBluetoothGatt.writeCharacteristic(mCharacteristic)) { if (!mChromeDevice.mBluetoothGatt.writeCharacteristic(mCharacteristic)) {
Log.i(TAG, "writeRemoteCharacteristic writeCharacteristic failed."); Log.i(TAG, "writeRemoteCharacteristic writeCharacteristic failed.");
return false; return false;
......
...@@ -605,6 +605,10 @@ class Wrappers { ...@@ -605,6 +605,10 @@ class Wrappers {
public boolean setValue(byte[] value) { public boolean setValue(byte[] value) {
return mCharacteristic.setValue(value); return mCharacteristic.setValue(value);
} }
public void setWriteType(int writeType) {
mCharacteristic.setWriteType(writeType);
}
} }
/** /**
......
...@@ -801,20 +801,15 @@ HRESULT BluetoothLowEnergyWrapper::ReadCharacteristicValue( ...@@ -801,20 +801,15 @@ HRESULT BluetoothLowEnergyWrapper::ReadCharacteristicValue(
HRESULT BluetoothLowEnergyWrapper::WriteCharacteristicValue( HRESULT BluetoothLowEnergyWrapper::WriteCharacteristicValue(
base::FilePath& service_path, base::FilePath& service_path,
const PBTH_LE_GATT_CHARACTERISTIC characteristic, const PBTH_LE_GATT_CHARACTERISTIC characteristic,
PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value) { PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value,
ULONG flags) {
base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ | base::File file(service_path, base::File::FLAG_OPEN | base::File::FLAG_READ |
base::File::FLAG_WRITE); base::File::FLAG_WRITE);
if (!file.IsValid()) if (!file.IsValid())
return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED); return HRESULT_FROM_WIN32(ERROR_OPEN_FAILED);
ULONG flag = BLUETOOTH_GATT_FLAG_NONE;
if (!characteristic->IsWritable) {
DCHECK(characteristic->IsWritableWithoutResponse);
flag |= BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE;
}
return BluetoothGATTSetCharacteristicValue( return BluetoothGATTSetCharacteristicValue(
file.GetPlatformFile(), characteristic, new_value, NULL, flag); file.GetPlatformFile(), characteristic, new_value, {}, flags);
} }
HRESULT BluetoothLowEnergyWrapper::RegisterGattEvents( HRESULT BluetoothLowEnergyWrapper::RegisterGattEvents(
......
...@@ -188,7 +188,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyWrapper { ...@@ -188,7 +188,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyWrapper {
virtual HRESULT WriteCharacteristicValue( virtual HRESULT WriteCharacteristicValue(
base::FilePath& service_path, base::FilePath& service_path,
const PBTH_LE_GATT_CHARACTERISTIC characteristic, const PBTH_LE_GATT_CHARACTERISTIC characteristic,
PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value); PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value,
ULONG flags);
// Register GATT events of |event_type| in the service with service device // Register GATT events of |event_type| in the service with service device
// path |service_path|. |event_parameter| is the event's parameter. |callback| // path |service_path|. |event_parameter| is the event's parameter. |callback|
......
...@@ -216,7 +216,15 @@ HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicValue( ...@@ -216,7 +216,15 @@ HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicValue(
HRESULT BluetoothLowEnergyWrapperFake::WriteCharacteristicValue( HRESULT BluetoothLowEnergyWrapperFake::WriteCharacteristicValue(
base::FilePath& service_path, base::FilePath& service_path,
const PBTH_LE_GATT_CHARACTERISTIC characteristic, const PBTH_LE_GATT_CHARACTERISTIC characteristic,
PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value) { PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value,
ULONG flags) {
// Web Bluetooth implementation currently only supports no flags or write
// without response flag even if Windows supports other flags
if (flags != BLUETOOTH_GATT_FLAG_NONE &&
flags != BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE) {
return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
}
GattCharacteristic* target_characteristic = GattCharacteristic* target_characteristic =
GetSimulatedGattCharacteristic(service_path, characteristic); GetSimulatedGattCharacteristic(service_path, characteristic);
if (target_characteristic == nullptr) if (target_characteristic == nullptr)
......
...@@ -130,7 +130,8 @@ class BluetoothLowEnergyWrapperFake : public BluetoothLowEnergyWrapper { ...@@ -130,7 +130,8 @@ class BluetoothLowEnergyWrapperFake : public BluetoothLowEnergyWrapper {
HRESULT WriteCharacteristicValue( HRESULT WriteCharacteristicValue(
base::FilePath& service_path, base::FilePath& service_path,
const PBTH_LE_GATT_CHARACTERISTIC characteristic, const PBTH_LE_GATT_CHARACTERISTIC characteristic,
PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value) override; PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value,
ULONG flags) override;
HRESULT RegisterGattEvents( HRESULT RegisterGattEvents(
base::FilePath& service_path, base::FilePath& service_path,
BTH_LE_GATT_EVENT_TYPE type, BTH_LE_GATT_EVENT_TYPE type,
......
...@@ -42,6 +42,12 @@ class BluetoothRemoteGattDescriptor; ...@@ -42,6 +42,12 @@ class BluetoothRemoteGattDescriptor;
class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristic class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristic
: public virtual BluetoothGattCharacteristic { : public virtual BluetoothGattCharacteristic {
public: public:
// Parameter for WriteRemoteCharacteristic
enum class WriteType {
kWithResponse,
kWithoutResponse,
};
// The ValueCallback is used to return the value of a remote characteristic // The ValueCallback is used to return the value of a remote characteristic
// upon a read request. // upon a read request.
using ValueCallback = base::OnceCallback<void(const std::vector<uint8_t>&)>; using ValueCallback = base::OnceCallback<void(const std::vector<uint8_t>&)>;
...@@ -136,6 +142,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristic ...@@ -136,6 +142,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristic
virtual void ReadRemoteCharacteristic(ValueCallback callback, virtual void ReadRemoteCharacteristic(ValueCallback callback,
ErrorCallback error_callback) = 0; ErrorCallback error_callback) = 0;
// Sends a write request to a remote characteristic with the value |value|
// using the specified |write_type|. |callback| is called to signal success
// and |error_callback| for failures. This method only applies to remote
// characteristics and will fail for those that are locally hosted.
virtual void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) = 0;
// DEPRECATED: Use WriteRemoteCharacteristic instead. This method remains // DEPRECATED: Use WriteRemoteCharacteristic instead. This method remains
// for backward compatibility. // for backward compatibility.
// Sends a write request to a remote characteristic with the value |value|. // Sends a write request to a remote characteristic with the value |value|.
......
...@@ -150,6 +150,45 @@ void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic( ...@@ -150,6 +150,45 @@ void BluetoothRemoteGattCharacteristicAndroid::ReadRemoteCharacteristic(
read_error_callback_ = std::move(error_callback); read_error_callback_ = std::move(error_callback);
} }
void BluetoothRemoteGattCharacteristicAndroid::WriteRemoteCharacteristic(
const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) {
if (read_pending_ || write_pending_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(error_callback),
BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
return;
}
AndroidWriteType android_write_type;
switch (write_type) {
case WriteType::kWithResponse:
android_write_type = AndroidWriteType::kDefault;
break;
case WriteType::kWithoutResponse:
android_write_type = AndroidWriteType::kNoResponse;
break;
}
JNIEnv* env = AttachCurrentThread();
if (!Java_ChromeBluetoothRemoteGattCharacteristic_writeRemoteCharacteristic(
env, j_characteristic_, base::android::ToJavaByteArray(env, value),
static_cast<int>(android_write_type))) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(error_callback),
BluetoothRemoteGattService::GATT_ERROR_FAILED));
return;
}
write_pending_ = true;
write_callback_ = std::move(callback);
write_error_callback_ = std::move(error_callback);
}
void BluetoothRemoteGattCharacteristicAndroid:: void BluetoothRemoteGattCharacteristicAndroid::
DeprecatedWriteRemoteCharacteristic(const std::vector<uint8_t>& value, DeprecatedWriteRemoteCharacteristic(const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
...@@ -164,7 +203,8 @@ void BluetoothRemoteGattCharacteristicAndroid:: ...@@ -164,7 +203,8 @@ void BluetoothRemoteGattCharacteristicAndroid::
JNIEnv* env = AttachCurrentThread(); JNIEnv* env = AttachCurrentThread();
if (!Java_ChromeBluetoothRemoteGattCharacteristic_writeRemoteCharacteristic( if (!Java_ChromeBluetoothRemoteGattCharacteristic_writeRemoteCharacteristic(
env, j_characteristic_, base::android::ToJavaByteArray(env, value))) { env, j_characteristic_, base::android::ToJavaByteArray(env, value),
static_cast<int>(AndroidWriteType::kNone))) {
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(std::move(error_callback), base::BindOnce(std::move(error_callback),
......
...@@ -65,6 +65,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicAndroid ...@@ -65,6 +65,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicAndroid
const BluetoothUUID& uuid) const override; const BluetoothUUID& uuid) const override;
void ReadRemoteCharacteristic(ValueCallback callback, void ReadRemoteCharacteristic(ValueCallback callback,
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void DeprecatedWriteRemoteCharacteristic( void DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
...@@ -109,6 +113,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicAndroid ...@@ -109,6 +113,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicAndroid
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
private: private:
// Android API characteristic write type flags.
// https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html
enum class AndroidWriteType {
kNone = 0,
kNoResponse = 1 << 0,
kDefault = 1 << 1,
kSigned = 1 << 2,
};
BluetoothRemoteGattCharacteristicAndroid( BluetoothRemoteGattCharacteristicAndroid(
BluetoothAdapterAndroid* adapter, BluetoothAdapterAndroid* adapter,
BluetoothRemoteGattServiceAndroid* service, BluetoothRemoteGattServiceAndroid* service,
......
...@@ -43,6 +43,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicMac ...@@ -43,6 +43,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicMac
bool IsNotifying() const override; bool IsNotifying() const override;
void ReadRemoteCharacteristic(ValueCallback callback, void ReadRemoteCharacteristic(ValueCallback callback,
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void DeprecatedWriteRemoteCharacteristic( void DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -152,6 +152,46 @@ void BluetoothRemoteGattCharacteristicMac::ReadRemoteCharacteristic( ...@@ -152,6 +152,46 @@ void BluetoothRemoteGattCharacteristicMac::ReadRemoteCharacteristic(
[GetCBPeripheral() readValueForCharacteristic:cb_characteristic_]; [GetCBPeripheral() readValueForCharacteristic:cb_characteristic_];
} }
void BluetoothRemoteGattCharacteristicMac::WriteRemoteCharacteristic(
const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) {
if (HasPendingRead() || HasPendingWrite()) {
DVLOG(1) << *this << ": Characteristic write already in progress.";
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(error_callback),
BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
return;
}
DVLOG(1) << *this << ": Write characteristic.";
write_characteristic_value_callbacks_ =
std::make_pair(std::move(callback), std::move(error_callback));
base::scoped_nsobject<NSData> nsdata_value(
[[NSData alloc] initWithBytes:value.data() length:value.size()]);
CBCharacteristicWriteType cb_write_type;
switch (write_type) {
case WriteType::kWithResponse:
cb_write_type = CBCharacteristicWriteWithResponse;
break;
case WriteType::kWithoutResponse:
cb_write_type = CBCharacteristicWriteWithoutResponse;
break;
}
[GetCBPeripheral() writeValue:nsdata_value
forCharacteristic:cb_characteristic_
type:cb_write_type];
if (cb_write_type == CBCharacteristicWriteWithoutResponse) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&BluetoothRemoteGattCharacteristicMac::DidWriteValue,
weak_ptr_factory_.GetWeakPtr(), nil));
}
}
void BluetoothRemoteGattCharacteristicMac::DeprecatedWriteRemoteCharacteristic( void BluetoothRemoteGattCharacteristicMac::DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -157,6 +157,40 @@ void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic( ...@@ -157,6 +157,40 @@ void BluetoothRemoteGattCharacteristicWin::ReadRemoteCharacteristic(
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
} }
void BluetoothRemoteGattCharacteristicWin::WriteRemoteCharacteristic(
const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) {
DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
if (characteristic_value_read_or_write_in_progress_) {
std::move(error_callback)
.Run(BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS);
return;
}
ULONG flags;
switch (write_type) {
case WriteType::kWithResponse:
flags = BLUETOOTH_GATT_FLAG_NONE;
break;
case WriteType::kWithoutResponse:
flags = BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE;
break;
}
characteristic_value_read_or_write_in_progress_ = true;
write_characteristic_value_callbacks_ =
std::make_pair(std::move(callback), std::move(error_callback));
task_manager_->PostWriteGattCharacteristicValue(
parent_service_->GetServicePath(), characteristic_info_.get(), value,
flags,
base::Bind(&BluetoothRemoteGattCharacteristicWin::
OnWriteRemoteCharacteristicValueCallback,
weak_ptr_factory_.GetWeakPtr()));
}
void BluetoothRemoteGattCharacteristicWin::DeprecatedWriteRemoteCharacteristic( void BluetoothRemoteGattCharacteristicWin::DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
...@@ -176,11 +210,17 @@ void BluetoothRemoteGattCharacteristicWin::DeprecatedWriteRemoteCharacteristic( ...@@ -176,11 +210,17 @@ void BluetoothRemoteGattCharacteristicWin::DeprecatedWriteRemoteCharacteristic(
return; return;
} }
ULONG flags = BLUETOOTH_GATT_FLAG_NONE;
if (!characteristic_info_->IsWritable) {
flags |= BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE;
}
characteristic_value_read_or_write_in_progress_ = true; characteristic_value_read_or_write_in_progress_ = true;
write_characteristic_value_callbacks_ = write_characteristic_value_callbacks_ =
std::make_pair(std::move(callback), std::move(error_callback)); std::make_pair(std::move(callback), std::move(error_callback));
task_manager_->PostWriteGattCharacteristicValue( task_manager_->PostWriteGattCharacteristicValue(
parent_service_->GetServicePath(), characteristic_info_.get(), value, parent_service_->GetServicePath(), characteristic_info_.get(), value,
flags,
base::Bind(&BluetoothRemoteGattCharacteristicWin:: base::Bind(&BluetoothRemoteGattCharacteristicWin::
OnWriteRemoteCharacteristicValueCallback, OnWriteRemoteCharacteristicValueCallback,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
......
...@@ -44,6 +44,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicWin ...@@ -44,6 +44,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicWin
bool IsNotifying() const override; bool IsNotifying() const override;
void ReadRemoteCharacteristic(ValueCallback callback, void ReadRemoteCharacteristic(ValueCallback callback,
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void DeprecatedWriteRemoteCharacteristic( void DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -45,6 +45,8 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: ...@@ -45,6 +45,8 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus_Success; GattCommunicationStatus_Success;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattReadResult; using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattReadResult;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattWriteOption;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattWriteOption_WriteWithoutResponse; GattWriteOption_WriteWithoutResponse;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
...@@ -201,19 +203,11 @@ void BluetoothRemoteGattCharacteristicWinrt::ReadRemoteCharacteristic( ...@@ -201,19 +203,11 @@ void BluetoothRemoteGattCharacteristicWinrt::ReadRemoteCharacteristic(
std::move(callback), std::move(error_callback)); std::move(callback), std::move(error_callback));
} }
void BluetoothRemoteGattCharacteristicWinrt:: void BluetoothRemoteGattCharacteristicWinrt::WriteRemoteCharacteristic(
DeprecatedWriteRemoteCharacteristic(const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, WriteType write_type,
ErrorCallback error_callback) { base::OnceClosure callback,
if (!(GetProperties() & PROPERTY_WRITE) && ErrorCallback error_callback) {
!(GetProperties() & PROPERTY_WRITE_WITHOUT_RESPONSE)) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(error_callback),
BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED));
return;
}
if (pending_read_callbacks_ || pending_write_callbacks_) { if (pending_read_callbacks_ || pending_write_callbacks_) {
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, FROM_HERE,
...@@ -246,13 +240,19 @@ void BluetoothRemoteGattCharacteristicWinrt:: ...@@ -246,13 +240,19 @@ void BluetoothRemoteGattCharacteristicWinrt::
return; return;
} }
GattWriteOption write_option;
switch (write_type) {
case WriteType::kWithResponse:
write_option = GattWriteOption_WriteWithResponse;
break;
case WriteType::kWithoutResponse:
write_option = GattWriteOption_WriteWithoutResponse;
break;
}
ComPtr<IAsyncOperation<GattWriteResult*>> write_value_op; ComPtr<IAsyncOperation<GattWriteResult*>> write_value_op;
hr = characteristic_3->WriteValueWithResultAndOptionAsync( hr = characteristic_3->WriteValueWithResultAndOptionAsync(
buffer.Get(), buffer.Get(), write_option, &write_value_op);
(GetProperties() & PROPERTY_WRITE) ? GattWriteOption_WriteWithResponse
: GattWriteOption_WriteWithoutResponse,
&write_value_op);
if (FAILED(hr)) { if (FAILED(hr)) {
BLUETOOTH_LOG(DEBUG) BLUETOOTH_LOG(DEBUG)
<< "GattCharacteristic::WriteValueWithResultAndOptionAsync failed: " << "GattCharacteristic::WriteValueWithResultAndOptionAsync failed: "
...@@ -284,6 +284,27 @@ void BluetoothRemoteGattCharacteristicWinrt:: ...@@ -284,6 +284,27 @@ void BluetoothRemoteGattCharacteristicWinrt::
std::move(callback), std::move(error_callback)); std::move(callback), std::move(error_callback));
} }
void BluetoothRemoteGattCharacteristicWinrt::
DeprecatedWriteRemoteCharacteristic(const std::vector<uint8_t>& value,
base::OnceClosure callback,
ErrorCallback error_callback) {
if (!(GetProperties() & PROPERTY_WRITE) &&
!(GetProperties() & PROPERTY_WRITE_WITHOUT_RESPONSE)) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(std::move(error_callback),
BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED));
return;
}
WriteType write_type = (GetProperties() & PROPERTY_WRITE)
? WriteType::kWithResponse
: WriteType::kWithoutResponse;
WriteRemoteCharacteristic(value, write_type, std::move(callback),
std::move(error_callback));
}
void BluetoothRemoteGattCharacteristicWinrt::UpdateDescriptors( void BluetoothRemoteGattCharacteristicWinrt::UpdateDescriptors(
BluetoothGattDiscovererWinrt* gatt_discoverer) { BluetoothGattDiscovererWinrt* gatt_discoverer) {
const auto* gatt_descriptors = const auto* gatt_descriptors =
......
...@@ -47,6 +47,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicWinrt ...@@ -47,6 +47,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicWinrt
BluetoothRemoteGattService* GetService() const override; BluetoothRemoteGattService* GetService() const override;
void ReadRemoteCharacteristic(ValueCallback callback, void ReadRemoteCharacteristic(ValueCallback callback,
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void DeprecatedWriteRemoteCharacteristic( void DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -869,6 +869,7 @@ void BluetoothTaskManagerWin::WriteGattCharacteristicValue( ...@@ -869,6 +869,7 @@ void BluetoothTaskManagerWin::WriteGattCharacteristicValue(
base::FilePath service_path, base::FilePath service_path,
BTH_LE_GATT_CHARACTERISTIC characteristic, BTH_LE_GATT_CHARACTERISTIC characteristic,
std::vector<uint8_t> new_value, std::vector<uint8_t> new_value,
ULONG flags,
const HResultCallback& callback) { const HResultCallback& callback) {
ULONG length = (ULONG)(sizeof(ULONG) + new_value.size()); ULONG length = (ULONG)(sizeof(ULONG) + new_value.size());
std::vector<UCHAR> data(length); std::vector<UCHAR> data(length);
...@@ -880,7 +881,7 @@ void BluetoothTaskManagerWin::WriteGattCharacteristicValue( ...@@ -880,7 +881,7 @@ void BluetoothTaskManagerWin::WriteGattCharacteristicValue(
HRESULT hr = le_wrapper_->WriteCharacteristicValue( HRESULT hr = le_wrapper_->WriteCharacteristicValue(
service_path, (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic), service_path, (PBTH_LE_GATT_CHARACTERISTIC)(&characteristic),
win_new_value); win_new_value, flags);
ui_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, hr)); ui_task_runner_->PostTask(FROM_HERE, base::BindOnce(callback, hr));
} }
...@@ -987,12 +988,14 @@ void BluetoothTaskManagerWin::PostWriteGattCharacteristicValue( ...@@ -987,12 +988,14 @@ void BluetoothTaskManagerWin::PostWriteGattCharacteristicValue(
const base::FilePath& service_path, const base::FilePath& service_path,
const PBTH_LE_GATT_CHARACTERISTIC characteristic, const PBTH_LE_GATT_CHARACTERISTIC characteristic,
const std::vector<uint8_t>& new_value, const std::vector<uint8_t>& new_value,
ULONG flags,
const HResultCallback& callback) { const HResultCallback& callback) {
DCHECK(ui_task_runner_->RunsTasksInCurrentSequence()); DCHECK(ui_task_runner_->RunsTasksInCurrentSequence());
bluetooth_task_runner_->PostTask( bluetooth_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
base::BindOnce(&BluetoothTaskManagerWin::WriteGattCharacteristicValue, base::BindOnce(&BluetoothTaskManagerWin::WriteGattCharacteristicValue,
this, service_path, *characteristic, new_value, callback)); this, service_path, *characteristic, new_value, flags,
callback));
} }
void BluetoothTaskManagerWin::PostRegisterGattCharacteristicValueChangedEvent( void BluetoothTaskManagerWin::PostRegisterGattCharacteristicValueChangedEvent(
......
...@@ -186,6 +186,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothTaskManagerWin ...@@ -186,6 +186,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothTaskManagerWin
const base::FilePath& service_path, const base::FilePath& service_path,
const PBTH_LE_GATT_CHARACTERISTIC characteristic, const PBTH_LE_GATT_CHARACTERISTIC characteristic,
const std::vector<uint8_t>& new_value, const std::vector<uint8_t>& new_value,
ULONG flags,
const HResultCallback& callback); const HResultCallback& callback);
// Post a task to register to receive value changed notifications from // Post a task to register to receive value changed notifications from
...@@ -319,6 +320,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothTaskManagerWin ...@@ -319,6 +320,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothTaskManagerWin
void WriteGattCharacteristicValue(base::FilePath service_path, void WriteGattCharacteristicValue(base::FilePath service_path,
BTH_LE_GATT_CHARACTERISTIC characteristic, BTH_LE_GATT_CHARACTERISTIC characteristic,
std::vector<uint8_t> new_value, std::vector<uint8_t> new_value,
ULONG flags,
const HResultCallback& callback); const HResultCallback& callback);
void RegisterGattCharacteristicValueChangedEvent( void RegisterGattCharacteristicValueChangedEvent(
base::FilePath service_path, base::FilePath service_path,
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include "device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h" #include "device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h"
#include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h" #include "device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "third_party/cros_system_api/dbus/bluetooth/dbus-constants.h"
#include "third_party/cros_system_api/dbus/service_constants.h" #include "third_party/cros_system_api/dbus/service_constants.h"
namespace bluez { namespace bluez {
...@@ -171,6 +172,36 @@ void BluetoothRemoteGattCharacteristicBlueZ::ReadRemoteCharacteristic( ...@@ -171,6 +172,36 @@ void BluetoothRemoteGattCharacteristicBlueZ::ReadRemoteCharacteristic(
std::move(error_callback))); std::move(error_callback)));
} }
void BluetoothRemoteGattCharacteristicBlueZ::WriteRemoteCharacteristic(
const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) {
DVLOG(1) << "Sending GATT characteristic write request to characteristic: "
<< GetIdentifier() << ", UUID: " << GetUUID().canonical_value()
<< ", with value: " << value << ", with response: "
<< ((write_type == WriteType::kWithoutResponse) ? "no" : "yes")
<< ".";
const char* type_option;
switch (write_type) {
case WriteType::kWithResponse:
type_option = bluetooth_gatt_characteristic::kTypeRequest;
break;
case WriteType::kWithoutResponse:
type_option = bluetooth_gatt_characteristic::kTypeCommand;
break;
}
bluez::BluezDBusManager::Get()
->GetBluetoothGattCharacteristicClient()
->WriteValue(
object_path(), value, type_option, std::move(callback),
base::BindOnce(&BluetoothRemoteGattCharacteristicBlueZ::OnWriteError,
weak_ptr_factory_.GetWeakPtr(),
std::move(error_callback)));
}
void BluetoothRemoteGattCharacteristicBlueZ:: void BluetoothRemoteGattCharacteristicBlueZ::
DeprecatedWriteRemoteCharacteristic(const std::vector<uint8_t>& value, DeprecatedWriteRemoteCharacteristic(const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
...@@ -182,7 +213,7 @@ void BluetoothRemoteGattCharacteristicBlueZ:: ...@@ -182,7 +213,7 @@ void BluetoothRemoteGattCharacteristicBlueZ::
bluez::BluezDBusManager::Get() bluez::BluezDBusManager::Get()
->GetBluetoothGattCharacteristicClient() ->GetBluetoothGattCharacteristicClient()
->WriteValue( ->WriteValue(
object_path(), value, std::move(callback), object_path(), value, "", std::move(callback),
base::BindOnce(&BluetoothRemoteGattCharacteristicBlueZ::OnWriteError, base::BindOnce(&BluetoothRemoteGattCharacteristicBlueZ::OnWriteError,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
std::move(error_callback))); std::move(error_callback)));
......
...@@ -56,6 +56,10 @@ class BluetoothRemoteGattCharacteristicBlueZ ...@@ -56,6 +56,10 @@ class BluetoothRemoteGattCharacteristicBlueZ
bool IsNotifying() const override; bool IsNotifying() const override;
void ReadRemoteCharacteristic(ValueCallback callback, void ReadRemoteCharacteristic(ValueCallback callback,
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void DeprecatedWriteRemoteCharacteristic( void DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chromecast/device/bluetooth/le/remote_characteristic.h" #include "chromecast/device/bluetooth/le/remote_characteristic.h"
#include "chromecast/device/bluetooth/le/remote_descriptor.h" #include "chromecast/device/bluetooth/le/remote_descriptor.h"
#include "chromecast/public/bluetooth/gatt.h"
#include "device/bluetooth/cast/bluetooth_remote_gatt_descriptor_cast.h" #include "device/bluetooth/cast/bluetooth_remote_gatt_descriptor_cast.h"
#include "device/bluetooth/cast/bluetooth_remote_gatt_service_cast.h" #include "device/bluetooth/cast/bluetooth_remote_gatt_service_cast.h"
#include "device/bluetooth/cast/bluetooth_utils.h" #include "device/bluetooth/cast/bluetooth_utils.h"
...@@ -141,6 +142,32 @@ void BluetoothRemoteGattCharacteristicCast::ReadRemoteCharacteristic( ...@@ -141,6 +142,32 @@ void BluetoothRemoteGattCharacteristicCast::ReadRemoteCharacteristic(
std::move(error_callback))); std::move(error_callback)));
} }
void BluetoothRemoteGattCharacteristicCast::WriteRemoteCharacteristic(
const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) {
using ChromecastWriteType = chromecast::bluetooth_v2_shlib::Gatt::WriteType;
ChromecastWriteType chromecast_write_type;
switch (write_type) {
case WriteType::kWithResponse:
chromecast_write_type = ChromecastWriteType::WRITE_TYPE_DEFAULT;
break;
case WriteType::kWithoutResponse:
chromecast_write_type = ChromecastWriteType::WRITE_TYPE_NO_RESPONSE;
break;
}
remote_characteristic_->WriteAuth(
chromecast::bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_NONE,
chromecast_write_type, value,
base::BindOnce(
&BluetoothRemoteGattCharacteristicCast::OnWriteRemoteCharacteristic,
weak_factory_.GetWeakPtr(), value, std::move(callback),
std::move(error_callback)));
}
void BluetoothRemoteGattCharacteristicCast::DeprecatedWriteRemoteCharacteristic( void BluetoothRemoteGattCharacteristicCast::DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -47,6 +47,10 @@ class BluetoothRemoteGattCharacteristicCast ...@@ -47,6 +47,10 @@ class BluetoothRemoteGattCharacteristicCast
BluetoothRemoteGattService* GetService() const override; BluetoothRemoteGattService* GetService() const override;
void ReadRemoteCharacteristic(ValueCallback callback, void ReadRemoteCharacteristic(ValueCallback callback,
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void DeprecatedWriteRemoteCharacteristic( void DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "dbus/bus.h" #include "dbus/bus.h"
#include "dbus/object_manager.h" #include "dbus/object_manager.h"
#include "dbus/values_util.h" #include "dbus/values_util.h"
#include "third_party/cros_system_api/dbus/bluetooth/dbus-constants.h"
#include "third_party/cros_system_api/dbus/service_constants.h" #include "third_party/cros_system_api/dbus/service_constants.h"
namespace bluez { namespace bluez {
...@@ -113,6 +114,7 @@ class BluetoothGattCharacteristicClientImpl ...@@ -113,6 +114,7 @@ class BluetoothGattCharacteristicClientImpl
// BluetoothGattCharacteristicClient override. // BluetoothGattCharacteristicClient override.
void WriteValue(const dbus::ObjectPath& object_path, void WriteValue(const dbus::ObjectPath& object_path,
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::StringPiece type_option,
base::OnceClosure callback, base::OnceClosure callback,
ErrorCallback error_callback) override { ErrorCallback error_callback) override {
dbus::ObjectProxy* object_proxy = dbus::ObjectProxy* object_proxy =
...@@ -128,8 +130,14 @@ class BluetoothGattCharacteristicClientImpl ...@@ -128,8 +130,14 @@ class BluetoothGattCharacteristicClientImpl
dbus::MessageWriter writer(&method_call); dbus::MessageWriter writer(&method_call);
writer.AppendArrayOfBytes(value.data(), value.size()); writer.AppendArrayOfBytes(value.data(), value.size());
// Append empty option dict // Append option dict
base::DictionaryValue dict; base::DictionaryValue dict;
if (!type_option.empty()) {
// NB: the "type" option was added in BlueZ 5.50. Older versions of BlueZ
// will ignore this option.
dict.SetStringKey(bluetooth_gatt_characteristic::kOptionType,
type_option);
}
dbus::AppendValueData(&writer, dict); dbus::AppendValueData(&writer, dict);
object_proxy->CallMethodWithErrorCallback( object_proxy->CallMethodWithErrorCallback(
......
...@@ -105,10 +105,12 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicClient ...@@ -105,10 +105,12 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicClient
ErrorCallback error_callback) = 0; ErrorCallback error_callback) = 0;
// Issues a request to write the value of GATT characteristic with object path // Issues a request to write the value of GATT characteristic with object path
// |object_path| with value |value|. Invokes |callback| on success and // |object_path| with value |value| and |type_option|. |type_option| is
// |error_callback| on failure. // bluetooth_gatt_characteristic::kTypeRequest or kTypeCommand, or "" to omit
// the option. Invokes |callback| on success and |error_callback| on failure.
virtual void WriteValue(const dbus::ObjectPath& object_path, virtual void WriteValue(const dbus::ObjectPath& object_path,
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::StringPiece type_option,
base::OnceClosure callback, base::OnceClosure callback,
ErrorCallback error_callback) = 0; ErrorCallback error_callback) = 0;
......
...@@ -649,8 +649,10 @@ void FakeBluetoothDeviceClient::ExecuteWrite( ...@@ -649,8 +649,10 @@ void FakeBluetoothDeviceClient::ExecuteWrite(
for (const auto& prepare_write_request : prepare_write_requests_) { for (const auto& prepare_write_request : prepare_write_requests_) {
bluez::BluezDBusManager::Get() bluez::BluezDBusManager::Get()
->GetBluetoothGattCharacteristicClient() ->GetBluetoothGattCharacteristicClient()
->WriteValue(prepare_write_request.first, prepare_write_request.second, ->WriteValue(std::get<0>(prepare_write_request),
base::DoNothing(), base::DoNothing()); std::get<1>(prepare_write_request),
std::get<2>(prepare_write_request), base::DoNothing(),
base::DoNothing());
} }
prepare_write_requests_.clear(); prepare_write_requests_.clear();
std::move(callback).Run(); std::move(callback).Run();
......
...@@ -384,7 +384,7 @@ class DEVICE_BLUETOOTH_EXPORT FakeBluetoothDeviceClient ...@@ -384,7 +384,7 @@ class DEVICE_BLUETOOTH_EXPORT FakeBluetoothDeviceClient
bool delay_start_discovery_; bool delay_start_discovery_;
// Pending prepare write requests. // Pending prepare write requests.
std::vector<std::pair<dbus::ObjectPath, std::vector<uint8_t>>> std::vector<std::tuple<dbus::ObjectPath, std::vector<uint8_t>, std::string>>
prepare_write_requests_; prepare_write_requests_;
bool should_leave_connections_pending_; bool should_leave_connections_pending_;
......
...@@ -206,6 +206,7 @@ void FakeBluetoothGattCharacteristicClient::ReadValue( ...@@ -206,6 +206,7 @@ void FakeBluetoothGattCharacteristicClient::ReadValue(
void FakeBluetoothGattCharacteristicClient::WriteValue( void FakeBluetoothGattCharacteristicClient::WriteValue(
const dbus::ObjectPath& object_path, const dbus::ObjectPath& object_path,
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::StringPiece type_option,
base::OnceClosure callback, base::OnceClosure callback,
ErrorCallback error_callback) { ErrorCallback error_callback) {
if (!authenticated_) { if (!authenticated_) {
......
...@@ -57,6 +57,7 @@ class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattCharacteristicClient ...@@ -57,6 +57,7 @@ class DEVICE_BLUETOOTH_EXPORT FakeBluetoothGattCharacteristicClient
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void WriteValue(const dbus::ObjectPath& object_path, void WriteValue(const dbus::ObjectPath& object_path,
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::StringPiece type_option,
base::OnceClosure callback, base::OnceClosure callback,
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void PrepareWriteValue(const dbus::ObjectPath& object_path, void PrepareWriteValue(const dbus::ObjectPath& object_path,
......
...@@ -693,6 +693,7 @@ class Fakes { ...@@ -693,6 +693,7 @@ class Fakes {
final int mProperties; final int mProperties;
final UUID mUuid; final UUID mUuid;
byte[] mValue; byte[] mValue;
int mWriteType;
static FakeBluetoothGattCharacteristic sRememberedCharacteristic; static FakeBluetoothGattCharacteristic sRememberedCharacteristic;
final ArrayList<Wrappers.BluetoothGattDescriptorWrapper> mDescriptors; final ArrayList<Wrappers.BluetoothGattDescriptorWrapper> mDescriptors;
...@@ -846,6 +847,11 @@ class Fakes { ...@@ -846,6 +847,11 @@ class Fakes {
mValue = value; mValue = value;
return true; return true;
} }
@Override
public void setWriteType(int writeType) {
mWriteType = writeType;
}
} }
/** /**
......
...@@ -138,6 +138,28 @@ void FakeRemoteGattCharacteristic::ReadRemoteCharacteristic( ...@@ -138,6 +138,28 @@ void FakeRemoteGattCharacteristic::ReadRemoteCharacteristic(
std::move(error_callback))); std::move(error_callback)));
} }
void FakeRemoteGattCharacteristic::WriteRemoteCharacteristic(
const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) {
// It doesn't make sense to dispatch a custom write response if the
// characteristic only supports write without response but we still need to
// run the callback because that's the guarantee the API makes.
if (write_type == WriteType::kWithoutResponse) {
last_written_value_ = value;
base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
std::move(callback));
return;
}
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(&FakeRemoteGattCharacteristic::DispatchWriteResponse,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
std::move(error_callback), value));
}
void FakeRemoteGattCharacteristic::DeprecatedWriteRemoteCharacteristic( void FakeRemoteGattCharacteristic::DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -85,6 +85,10 @@ class FakeRemoteGattCharacteristic ...@@ -85,6 +85,10 @@ class FakeRemoteGattCharacteristic
device::BluetoothRemoteGattService* GetService() const override; device::BluetoothRemoteGattService* GetService() const override;
void ReadRemoteCharacteristic(ValueCallback callback, void ReadRemoteCharacteristic(ValueCallback callback,
ErrorCallback error_callback) override; ErrorCallback error_callback) override;
void WriteRemoteCharacteristic(const std::vector<uint8_t>& value,
WriteType write_type,
base::OnceClosure callback,
ErrorCallback error_callback) override;
void DeprecatedWriteRemoteCharacteristic( void DeprecatedWriteRemoteCharacteristic(
const std::vector<uint8_t>& value, const std::vector<uint8_t>& value,
base::OnceClosure callback, base::OnceClosure callback,
......
...@@ -74,6 +74,17 @@ class MockBluetoothGattCharacteristic ...@@ -74,6 +74,17 @@ class MockBluetoothGattCharacteristic
ReadRemoteCharacteristic_(c, ec); ReadRemoteCharacteristic_(c, ec);
} }
MOCK_METHOD2(ReadRemoteCharacteristic_, void(ValueCallback&, ErrorCallback&)); MOCK_METHOD2(ReadRemoteCharacteristic_, void(ValueCallback&, ErrorCallback&));
void WriteRemoteCharacteristic(const std::vector<uint8_t>& v,
WriteType t,
base::OnceClosure c,
ErrorCallback ec) override {
WriteRemoteCharacteristic_(v, t, c, ec);
}
MOCK_METHOD4(WriteRemoteCharacteristic_,
void(const std::vector<uint8_t>&,
WriteType,
base::OnceClosure&,
ErrorCallback&));
void DeprecatedWriteRemoteCharacteristic(const std::vector<uint8_t>& v, void DeprecatedWriteRemoteCharacteristic(const std::vector<uint8_t>& v,
base::OnceClosure c, base::OnceClosure c,
ErrorCallback ec) override { ErrorCallback ec) override {
......
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