Commit 4e58d3d7 authored by jlebel's avatar jlebel Committed by Commit bot
Browse files

bluetooth: mac: write characteristic implementation

Adding implementing write characteristic in BluetoothRemoteGattCharacteristicMac, and adding unit tests, mock and simulation.

BUG=609067

Review-Url: https://codereview.chromium.org/2074563002
Cr-Commit-Position: refs/heads/master@{#402367}
parent 30edb129
......@@ -94,6 +94,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceMac
void DidModifyServices(NSArray* invalidatedServices);
void DidDiscoverCharacteristics(CBService* cb_service, NSError* error);
void DidUpdateValue(CBCharacteristic* characteristic, NSError* error);
void DidWriteValue(CBCharacteristic* characteristic, NSError* error);
// Updates information about the device.
virtual void Update(NSDictionary* advertisement_data, int rssi);
......
......@@ -317,6 +317,15 @@ void BluetoothLowEnergyDeviceMac::DidUpdateValue(
gatt_service->DidUpdateValue(characteristic, error);
}
void BluetoothLowEnergyDeviceMac::DidWriteValue(
CBCharacteristic* characteristic,
NSError* error) {
BluetoothRemoteGattServiceMac* gatt_service =
GetBluetoothRemoteGattService(characteristic.service);
DCHECK(gatt_service);
gatt_service->DidWriteValue(characteristic, error);
}
// static
std::string BluetoothLowEnergyDeviceMac::GetPeripheralIdentifier(
CBPeripheral* peripheral) {
......
......@@ -35,6 +35,10 @@ class BluetoothLowEnergyPeripheralBridge {
device_mac_->DidUpdateValue(characteristic, error);
}
void DidWriteValue(CBCharacteristic* characteristic, NSError* error) {
device_mac_->DidWriteValue(characteristic, error);
}
CBPeripheral* GetPeripheral() { return device_mac_->GetPeripheral(); }
private:
......@@ -80,4 +84,9 @@ class BluetoothLowEnergyPeripheralBridge {
bridge_->DidUpdateValue(characteristic, error);
}
- (void)peripheral:(CBPeripheral*)peripheral
didWriteValueForCharacteristic:(nonnull CBCharacteristic*)characteristic
error:(nullable NSError*)error {
bridge_->DidWriteValue(characteristic, error);
}
@end
......@@ -9,7 +9,12 @@
#include "base/mac/scoped_nsobject.h"
#if defined(__OBJC__)
#import <CoreBluetooth/CoreBluetooth.h>
#else
@class CBCharacteristic;
typedef NS_ENUM(NSInteger, CBCharacteristicWriteType);
#endif // defined(__OBJC__)
namespace device {
......@@ -55,8 +60,15 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicMac
// Called by the BluetoothRemoteGattServiceMac instance when the
// characteristics value has been read.
void DidUpdateValue(NSError* error);
// Called by the BluetoothRemoteGattServiceMac instance when the
// characteristics value has been written.
void DidWriteValue(NSError* error);
// Returns true if the characteristic is readable.
bool IsReadable() const;
// Returns true if the characteristic is writable.
bool IsWritable() const;
// Returns the write type (with or without responses).
CBCharacteristicWriteType GetCBWriteType() const;
// Returns CoreBluetooth characteristic.
CBCharacteristic* GetCBCharacteristic() const;
......@@ -74,6 +86,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattCharacteristicMac
bool characteristic_value_read_or_write_in_progress_;
// ReadRemoteCharacteristic request callbacks.
std::pair<ValueCallback, ErrorCallback> read_characteristic_value_callbacks_;
// WriteRemoteCharacteristic request callbacks.
std::pair<base::Closure, ErrorCallback> write_characteristic_value_callbacks_;
};
} // namespace device
......
......@@ -4,8 +4,6 @@
#include "device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h"
#import <CoreBluetooth/CoreBluetooth.h>
#include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h"
#include "device/bluetooth/bluetooth_adapter_mac.h"
......@@ -162,11 +160,41 @@ void BluetoothRemoteGattCharacteristicMac::WriteRemoteCharacteristic(
const std::vector<uint8_t>& new_value,
const base::Closure& callback,
const ErrorCallback& error_callback) {
NOTIMPLEMENTED();
if (!IsWritable()) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(error_callback,
BluetoothRemoteGattService::GATT_ERROR_NOT_PERMITTED));
return;
}
if (characteristic_value_read_or_write_in_progress_) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(error_callback,
BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS));
return;
}
characteristic_value_read_or_write_in_progress_ = true;
write_characteristic_value_callbacks_ =
std::make_pair(callback, error_callback);
base::scoped_nsobject<NSData> nsdata_value(
[[NSData alloc] initWithBytes:new_value.data() length:new_value.size()]);
CBCharacteristicWriteType write_type = GetCBWriteType();
[gatt_service_->GetCBPeripheral() writeValue:nsdata_value
forCharacteristic:cb_characteristic_
type:write_type];
if (write_type == CBCharacteristicWriteWithoutResponse) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::Bind(&BluetoothRemoteGattCharacteristicMac::DidWriteValue,
base::Unretained(this), nil));
}
}
void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) {
if (!characteristic_value_read_or_write_in_progress_) {
// In case of buggy device, nothing should be done if receiving extra
// read confirmation.
return;
}
std::pair<ValueCallback, ErrorCallback> callbacks;
......@@ -188,13 +216,50 @@ void BluetoothRemoteGattCharacteristicMac::DidUpdateValue(NSError* error) {
callbacks.first.Run(value_);
}
void BluetoothRemoteGattCharacteristicMac::DidWriteValue(NSError* error) {
if (!characteristic_value_read_or_write_in_progress_) {
// In case of buggy device, nothing should be done if receiving extra
// write confirmation.
return;
}
std::pair<base::Closure, ErrorCallback> callbacks;
callbacks.swap(write_characteristic_value_callbacks_);
characteristic_value_read_or_write_in_progress_ = false;
if (error) {
VLOG(1) << "Bluetooth error while writing for characteristic, domain: "
<< error.domain.UTF8String << ", error code: " << error.code;
BluetoothGattService::GattErrorCode error_code =
BluetoothDeviceMac::GetGattErrorCodeFromNSError(error);
callbacks.second.Run(error_code);
return;
}
NSData* nsdata_value = cb_characteristic_.get().value;
const uint8_t* buffer = static_cast<const uint8_t*>(nsdata_value.bytes);
std::vector<uint8_t> gatt_value(buffer, buffer + nsdata_value.length);
gatt_service_->GetMacAdapter()->NotifyGattCharacteristicValueChanged(this,
value_);
callbacks.first.Run();
}
bool BluetoothRemoteGattCharacteristicMac::IsReadable() const {
return GetProperties() & BluetoothGattCharacteristic::PROPERTY_READ;
}
bool BluetoothRemoteGattCharacteristicMac::IsWritable() const {
BluetoothGattCharacteristic::Properties properties = GetProperties();
return (properties & BluetoothGattCharacteristic::PROPERTY_WRITE) ||
(properties & PROPERTY_WRITE_WITHOUT_RESPONSE);
}
CBCharacteristicWriteType BluetoothRemoteGattCharacteristicMac::GetCBWriteType()
const {
return (GetProperties() & BluetoothGattCharacteristic::PROPERTY_WRITE)
? CBCharacteristicWriteWithResponse
: CBCharacteristicWriteWithoutResponse;
}
CBCharacteristic* BluetoothRemoteGattCharacteristicMac::GetCBCharacteristic()
const {
return cb_characteristic_.get();
}
} // namespace device.
......@@ -317,9 +317,13 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, ReadRemoteCharacteristic_Empty) {
}
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests WriteRemoteCharacteristic with empty value buffer.
TEST_F(BluetoothRemoteGattCharacteristicTest, WriteRemoteCharacteristic_Empty) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -335,7 +339,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, WriteRemoteCharacteristic_Empty) {
EXPECT_EQ(empty_vector, last_write_value_);
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
// Tests ReadRemoteCharacteristic completing after Chrome objects are deleted.
......@@ -370,6 +374,10 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
// delegate is set to nil.
TEST_F(BluetoothRemoteGattCharacteristicTest,
WriteRemoteCharacteristic_AfterDeleted) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -450,9 +458,13 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests WriteRemoteCharacteristic with non-empty value buffer.
TEST_F(BluetoothRemoteGattCharacteristicTest, WriteRemoteCharacteristic) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -467,7 +479,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, WriteRemoteCharacteristic) {
EXPECT_EQ(1, gatt_write_characteristic_attempts_);
EXPECT_EQ(test_vector, last_write_value_);
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests ReadRemoteCharacteristic and GetValue multiple times.
......@@ -507,9 +519,13 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, ReadRemoteCharacteristic_Twice) {
}
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests WriteRemoteCharacteristic multiple times.
TEST_F(BluetoothRemoteGattCharacteristicTest, WriteRemoteCharacteristic_Twice) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -538,7 +554,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, WriteRemoteCharacteristic_Twice) {
EXPECT_EQ(0, error_callback_count_);
EXPECT_EQ(empty_vector, last_write_value_);
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests ReadRemoteCharacteristic on two characteristics.
......@@ -578,10 +594,14 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
}
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests WriteRemoteCharacteristic on two characteristics.
TEST_F(BluetoothRemoteGattCharacteristicTest,
WriteRemoteCharacteristic_MultipleCharacteristics) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -590,7 +610,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
characteristic1_->WriteRemoteCharacteristic(
test_vector1, GetCallback(Call::EXPECTED),
GetGattErrorCallback(Call::NOT_EXPECTED));
#ifdef OS_ANDROID
#if defined(OS_ANDROID) || defined(OS_MACOSX)
EXPECT_EQ(test_vector1, last_write_value_);
#endif
......@@ -599,7 +619,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
characteristic2_->WriteRemoteCharacteristic(
test_vector2, GetCallback(Call::EXPECTED),
GetGattErrorCallback(Call::NOT_EXPECTED));
#ifdef OS_ANDROID
#if defined(OS_ANDROID) || defined(OS_MACOSX)
EXPECT_EQ(test_vector2, last_write_value_);
#endif
......@@ -607,12 +627,12 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
EXPECT_EQ(0, error_callback_count_);
SimulateGattCharacteristicWrite(characteristic1_);
#ifndef OS_ANDROID
#if !(defined(OS_ANDROID) || defined(OS_MACOSX))
EXPECT_EQ(test_vector1, last_write_value_);
#endif
SimulateGattCharacteristicWrite(characteristic2_);
#ifndef OS_ANDROID
#if !(defined(OS_ANDROID) || defined(OS_MACOSX))
EXPECT_EQ(test_vector2, last_write_value_);
#endif
......@@ -622,7 +642,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
// TODO(591740): Remove if define for OS_ANDROID in this test.
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests ReadRemoteCharacteristic asynchronous error.
......@@ -649,9 +669,13 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, ReadError) {
}
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests WriteRemoteCharacteristic asynchronous error.
TEST_F(BluetoothRemoteGattCharacteristicTest, WriteError) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -667,7 +691,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, WriteError) {
EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH,
last_gatt_error_code_);
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID)
// Tests ReadRemoteCharacteristic synchronous error.
......@@ -702,6 +726,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest, ReadSynchronousError) {
#if defined(OS_ANDROID)
// Tests WriteRemoteCharacteristic synchronous error.
// This test doesn't apply to macOS synchronous API does exist.
TEST_F(BluetoothRemoteGattCharacteristicTest, WriteSynchronousError) {
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate());
......@@ -763,10 +788,14 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
}
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests WriteRemoteCharacteristic error with a pending write operation.
TEST_F(BluetoothRemoteGattCharacteristicTest,
WriteRemoteCharacteristic_WritePending) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -791,12 +820,16 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
EXPECT_EQ(1, callback_count_);
EXPECT_EQ(0, error_callback_count_);
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests ReadRemoteCharacteristic error with a pending write operation.
TEST_F(BluetoothRemoteGattCharacteristicTest,
ReadRemoteCharacteristic_WritePending) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_READ |
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -822,12 +855,16 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
EXPECT_EQ(1, callback_count_);
EXPECT_EQ(0, error_callback_count_);
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
// Tests WriteRemoteCharacteristic error with a pending Read operation.
TEST_F(BluetoothRemoteGattCharacteristicTest,
WriteRemoteCharacteristic_ReadPending) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
ASSERT_NO_FATAL_FAILURE(FakeCharacteristicBoilerplate(
BluetoothRemoteGattCharacteristic::PROPERTY_READ |
BluetoothRemoteGattCharacteristic::PROPERTY_WRITE));
......@@ -852,7 +889,7 @@ TEST_F(BluetoothRemoteGattCharacteristicTest,
EXPECT_EQ(1, callback_count_);
EXPECT_EQ(0, error_callback_count_);
}
#endif // defined(OS_ANDROID) || defined(OS_WIN)
#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN)
#if defined(OS_ANDROID) || defined(OS_WIN)
// StartNotifySession fails if characteristic doesn't have Notify or Indicate
......
......@@ -54,9 +54,12 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattServiceMac
// Called by the BluetoothLowEnergyDeviceMac instance when the characteristics
// has been discovered.
void DidDiscoverCharacteristics();
// Called by the BluetoothRemoteGattServiceMac instance when the
// Called by the BluetoothLowEnergyDeviceMac instance when the
// characteristics value has been read.
void DidUpdateValue(CBCharacteristic* characteristic, NSError* error);
// Called by the BluetoothLowEnergyDeviceMac instance when the
// characteristics value has been written.
void DidWriteValue(CBCharacteristic* characteristic, NSError* error);
// Returns true if the characteristics has been discovered.
bool IsDiscoveryComplete();
......
......@@ -128,6 +128,15 @@ void BluetoothRemoteGattServiceMac::DidUpdateValue(
gatt_characteristic->DidUpdateValue(error);
}
void BluetoothRemoteGattServiceMac::DidWriteValue(
CBCharacteristic* characteristic,
NSError* error) {
BluetoothRemoteGattCharacteristicMac* gatt_characteristic =
GetBluetoothRemoteGattCharacteristicMac(characteristic);
DCHECK(gatt_characteristic);
gatt_characteristic->DidWriteValue(error);
}
bool BluetoothRemoteGattServiceMac::IsDiscoveryComplete() {
return is_discovery_complete_;
}
......
......@@ -58,6 +58,11 @@ class BluetoothTestMac : public BluetoothTestBase {
void SimulateGattCharacteristicReadError(
BluetoothRemoteGattCharacteristic* characteristic,
BluetoothRemoteGattService::GattErrorCode) override;
void SimulateGattCharacteristicWrite(
BluetoothRemoteGattCharacteristic* characteristic) override;
void SimulateGattCharacteristicWriteError(
BluetoothRemoteGattCharacteristic* characteristic,
BluetoothRemoteGattService::GattErrorCode error_code) override;
void SimulateGattCharacteristicRemoved(
BluetoothRemoteGattService* service,
BluetoothRemoteGattCharacteristic* characteristic) override;
......@@ -69,6 +74,7 @@ class BluetoothTestMac : public BluetoothTestBase {
// Callback for the bluetooth peripheral mock.
void OnFakeBluetoothServiceDiscovery();
void OnFakeBluetoothCharacteristicReadValue();
void OnFakeBluetoothCharacteristicWriteValue(std::vector<uint8_t> value);
protected:
class ScopedMockCentralManager;
......
......@@ -309,6 +309,22 @@ void BluetoothTestMac::SimulateGattCharacteristicReadError(
[characteristic_mock simulateReadWithValue:nil error:error];
}
void BluetoothTestMac::SimulateGattCharacteristicWrite(
BluetoothRemoteGattCharacteristic* characteristic) {
MockCBCharacteristic* characteristic_mock =
GetCBMockCharacteristic(characteristic);
[characteristic_mock simulateWriteWithError:nil];
}
void BluetoothTestMac::SimulateGattCharacteristicWriteError(
BluetoothRemoteGattCharacteristic* characteristic,
BluetoothRemoteGattService::GattErrorCode error_code) {
MockCBCharacteristic* characteristic_mock =
GetCBMockCharacteristic(characteristic);
NSError* error = BluetoothDeviceMac::GetNSErrorFromGattErrorCode(error_code);
[characteristic_mock simulateWriteWithError:error];
}
void BluetoothTestMac::SimulateGattCharacteristicRemoved(
BluetoothRemoteGattService* service,
BluetoothRemoteGattCharacteristic* characteristic) {
......@@ -343,6 +359,12 @@ void BluetoothTest::OnFakeBluetoothCharacteristicReadValue() {
gatt_read_characteristic_attempts_++;
}
void BluetoothTest::OnFakeBluetoothCharacteristicWriteValue(
std::vector<uint8_t> value) {
last_write_value_ = value;
gatt_write_characteristic_attempts_++;
}
MockCBPeripheral* BluetoothTestMac::GetMockCBPeripheral(
BluetoothRemoteGattService* service) const {
BluetoothDevice* device = service->GetDevice();
......
......@@ -22,6 +22,7 @@
// Methods for faking events.
- (void)simulateReadWithValue:(NSData*)value error:(NSError*)error;
- (void)simulateWriteWithError:(NSError*)error;
@end
......
......@@ -137,6 +137,13 @@ CBCharacteristicProperties GattCharacteristicPropertyToCBCharacteristicProperty(
error:error];
}
- (void)simulateWriteWithError:(NSError*)error {
CBPeripheral* peripheral = _service.peripheral;
[peripheral.delegate peripheral:peripheral
didWriteValueForCharacteristic:self.characteristic
error:error];
}
- (CBUUID*)UUID {
return _UUID.get();
}
......
......@@ -96,6 +96,15 @@ using base::scoped_nsobject;
_bluetoothTestMac->OnFakeBluetoothCharacteristicReadValue();
}
- (void)writeValue:(NSData*)data
forCharacteristic:(CBCharacteristic*)characteristic
type:(CBCharacteristicWriteType)type {
DCHECK(_bluetoothTestMac);
const uint8_t* buffer = static_cast<const uint8_t*>(data.bytes);
std::vector<uint8_t> value(buffer, buffer + data.length);
_bluetoothTestMac->OnFakeBluetoothCharacteristicWriteValue(value);
}
- (void)removeAllServices {
[_services.get() removeAllObjects];
}
......
......@@ -1387,9 +1387,6 @@ crbug.com/605059 [ Retina ] fast/text/international/rtl-negative-letter-spacing.
crbug.com/610464 [ Win7 Debug ] inspector/components/throttler.html [ Failure Pass ]
# TODO(jlebel): Remove when methods are implemented.
crbug.com/609067 [ Mac ] bluetooth/gattserverdisconnected-event/reconnect-during-disconnected-event.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/connect/connect-disconnected-connect.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/gattserverdisconnected-event/disconnected.html [ Skip ]
crbug.com/609068 [ Mac ] bluetooth/notifications/add-listener-after-promise.html [ Skip ]
crbug.com/609068 [ Mac ] bluetooth/notifications/add-multiple-event-listeners.html [ Skip ]
crbug.com/609068 [ Mac ] bluetooth/notifications/characteristic-does-not-support-notifications.html [ Skip ]
......@@ -1409,15 +1406,6 @@ crbug.com/609068 [ Mac ] bluetooth/notifications/start-succeeds.html [ Skip ]
crbug.com/609068 [ Mac ] bluetooth/notifications/start-twice-in-a-row.html [ Skip ]
crbug.com/609068 [ Mac ] bluetooth/notifications/stop-twice.html [ Skip ]
crbug.com/609068 [ Mac ] bluetooth/notifications/stop-without-starting.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/readValue/blacklisted-characteristic.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/writeValue/blacklisted-characteristic.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/writeValue/characteristic-is-removed.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/writeValue/device-goes-out-of-range.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/writeValue/service-is-removed.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/writeValue/value-too-long.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/writeValue/write-fails.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/writeValue/write-succeeds.html [ Skip ]
crbug.com/609067 [ Mac ] bluetooth/writeValue/write-updates-value.html [ Skip ]
crbug.com/487344 compositing/video/video-controls-layer-creation.html [ Failure ]
crbug.com/487344 fast/hidpi/video-controls-in-hidpi.html [ Failure ]
......
......@@ -174,13 +174,6 @@ private:
ScriptPromise BluetoothRemoteGATTCharacteristic::writeValue(ScriptState* scriptState, const DOMArrayPiece& value)
{
#if OS(MACOSX)
// TODO(jlebel): Remove when writeValue is implemented.
return ScriptPromise::rejectWithDOMException(scriptState,
DOMException::create(NotSupportedError,
"writeValue is not implemented yet. See https://goo.gl/J6ASzs"));
#endif // OS(MACOSX)
WebBluetooth* webbluetooth = BluetoothSupplement::fromScriptState(scriptState);
// Partial implementation of writeValue algorithm:
// https://webbluetoothchrome.github.io/web-bluetooth/#dom-bluetoothgattcharacteristic-writevalue
......
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