diff --git a/chromecast/device/bluetooth/le/gatt_client_manager_impl_test.cc b/chromecast/device/bluetooth/le/gatt_client_manager_impl_test.cc index 18632cf39655dc..ac7e1fe6fdb7eb 100644 --- a/chromecast/device/bluetooth/le/gatt_client_manager_impl_test.cc +++ b/chromecast/device/bluetooth/le/gatt_client_manager_impl_test.cc @@ -289,13 +289,6 @@ TEST_F(GattClientManagerTest, RemoteDeviceServices) { bluetooth_v2_shlib::Gatt::Client::Delegate* delegate = gatt_client_->delegate(); delegate->OnServicesAdded(kTestAddr1, kServices); - - device->GetServices(base::BindOnce( - [](std::vector>* pservices, - std::vector> services) { - *pservices = services; - }, - &services)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(kServices.size(), GetServices(device.get()).size()); @@ -528,5 +521,74 @@ TEST_F(GattClientManagerTest, FakeCccd) { } } +TEST_F(GattClientManagerTest, WriteType) { + const std::vector kTestData1 = {0x1, 0x2, 0x3}; + + bluetooth_v2_shlib::Gatt::Service service; + bluetooth_v2_shlib::Gatt::Characteristic characteristic; + + service.uuid = {{0x1}}; + service.handle = 0x1; + service.primary = true; + + characteristic.uuid = {{0x1, 0x1}}; + characteristic.handle = 0x2; + characteristic.permissions = bluetooth_v2_shlib::Gatt::PERMISSION_WRITE; + characteristic.properties = bluetooth_v2_shlib::Gatt::PROPERTY_WRITE; + service.characteristics.push_back(characteristic); + + characteristic.uuid = {{0x1, 0x2}}; + characteristic.handle = 0x3; + characteristic.permissions = bluetooth_v2_shlib::Gatt::PERMISSION_WRITE; + characteristic.properties = + bluetooth_v2_shlib::Gatt::PROPERTY_WRITE_NO_RESPONSE; + service.characteristics.push_back(characteristic); + + characteristic.uuid = {{0x1, 0x3}}; + characteristic.handle = 0x4; + characteristic.permissions = bluetooth_v2_shlib::Gatt::PERMISSION_WRITE; + characteristic.properties = bluetooth_v2_shlib::Gatt::PROPERTY_SIGNED_WRITE; + service.characteristics.push_back(characteristic); + + Connect(kTestAddr1); + bluetooth_v2_shlib::Gatt::Client::Delegate* delegate = + gatt_client_->delegate(); + delegate->OnServicesAdded(kTestAddr1, {service}); + + scoped_refptr device = GetDevice(kTestAddr1); + + std::vector> services = + GetServices(device.get()); + ASSERT_EQ(1u, services.size()); + + std::vector> characteristics = + services[0]->GetCharacteristics(); + ASSERT_EQ(3u, characteristics.size()); + + using WriteType = bluetooth_v2_shlib::Gatt::WriteType; + + // The current implementation of RemoteDevice will put the characteristics in + // the order reported by libcast_bluetooth. + const WriteType kWriteTypes[] = {WriteType::WRITE_TYPE_DEFAULT, + WriteType::WRITE_TYPE_NO_RESPONSE, + WriteType::WRITE_TYPE_SIGNED}; + + for (size_t i = 0; i < characteristics.size(); ++i) { + const auto& characteristic = characteristics[i]; + EXPECT_CALL( + *gatt_client_, + WriteCharacteristic(kTestAddr1, characteristic->characteristic(), + bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_NONE, + kWriteTypes[i], kTestData1)) + .WillOnce(Return(true)); + + base::MockCallback write_cb; + EXPECT_CALL(write_cb, Run(true)); + characteristic->Write(kTestData1, write_cb.Get()); + delegate->OnCharacteristicWriteResponse(kTestAddr1, true, + characteristic->handle()); + } +} + } // namespace bluetooth } // namespace chromecast diff --git a/chromecast/device/bluetooth/le/mock_remote_characteristic.h b/chromecast/device/bluetooth/le/mock_remote_characteristic.h index d9d7876141666a..8b7beddffe9f90 100644 --- a/chromecast/device/bluetooth/le/mock_remote_characteristic.h +++ b/chromecast/device/bluetooth/le/mock_remote_characteristic.h @@ -44,13 +44,10 @@ class MockRemoteCharacteristic : public RemoteCharacteristic { const std::vector& value, StatusCallback callback) override {} - MOCK_METHOD2(Write, - bool(bluetooth_v2_shlib::Gatt::WriteType write_type, - const std::vector& value)); - void Write(bluetooth_v2_shlib::Gatt::WriteType write_type, - const std::vector& value, + MOCK_METHOD1(Write, bool(const std::vector& value)); + void Write(const std::vector& value, StatusCallback callback) override { - std::move(callback).Run(Write(write_type, value)); + std::move(callback).Run(Write(value)); } MOCK_METHOD0(NotificationEnabled, bool()); diff --git a/chromecast/device/bluetooth/le/remote_characteristic.h b/chromecast/device/bluetooth/le/remote_characteristic.h index 8c4b601434b0a5..0d900b10f82960 100644 --- a/chromecast/device/bluetooth/le/remote_characteristic.h +++ b/chromecast/device/bluetooth/le/remote_characteristic.h @@ -61,10 +61,10 @@ class RemoteCharacteristic const std::vector& value, StatusCallback callback) = 0; - // Write |value| to the characteristic with |write_type|. Will retry if - // auth_req isn't met. When completed, |callback| will be called. - virtual void Write(bluetooth_v2_shlib::Gatt::WriteType write_type, - const std::vector& value, + // Write |value| to the characteristic inferring write_type from + // |permissions()|. Will retry if auth_req isn't met. When completed, + // |callback| will be called. + virtual void Write(const std::vector& value, StatusCallback callback) = 0; // Returns true if notifications are enabled. diff --git a/chromecast/device/bluetooth/le/remote_characteristic_impl.cc b/chromecast/device/bluetooth/le/remote_characteristic_impl.cc index a1a301694671dd..d595cc07db348f 100644 --- a/chromecast/device/bluetooth/le/remote_characteristic_impl.cc +++ b/chromecast/device/bluetooth/le/remote_characteristic_impl.cc @@ -234,12 +234,26 @@ void RemoteCharacteristicImpl::WriteAuth( write_callback_ = std::move(callback); } -void RemoteCharacteristicImpl::Write( - bluetooth_v2_shlib::Gatt::WriteType write_type, - const std::vector& value, - StatusCallback callback) { - return WriteAuth(bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_NONE, write_type, - value, std::move(callback)); +void RemoteCharacteristicImpl::Write(const std::vector& value, + StatusCallback callback) { + using WriteType = bluetooth_v2_shlib::Gatt::WriteType; + using Properties = bluetooth_v2_shlib::Gatt::Properties; + + WriteType write_type = WriteType::WRITE_TYPE_NONE; + if (properties() & Properties::PROPERTY_WRITE) { + write_type = WriteType::WRITE_TYPE_DEFAULT; + } else if (properties() & Properties::PROPERTY_WRITE_NO_RESPONSE) { + write_type = WriteType::WRITE_TYPE_NO_RESPONSE; + } else if (properties() & Properties::PROPERTY_SIGNED_WRITE) { + write_type = WriteType::WRITE_TYPE_SIGNED; + } else { + LOG(ERROR) << "Write not supported. Properties: " + << static_cast(properties()); + EXEC_CB_AND_RET(callback, false); + } + + WriteAuth(bluetooth_v2_shlib::Gatt::Client::AUTH_REQ_NONE, write_type, value, + std::move(callback)); } bool RemoteCharacteristicImpl::NotificationEnabled() { diff --git a/chromecast/device/bluetooth/le/remote_characteristic_impl.h b/chromecast/device/bluetooth/le/remote_characteristic_impl.h index a4cf3b44cd209f..fcb4027d331660 100644 --- a/chromecast/device/bluetooth/le/remote_characteristic_impl.h +++ b/chromecast/device/bluetooth/le/remote_characteristic_impl.h @@ -37,8 +37,7 @@ class RemoteCharacteristicImpl : public RemoteCharacteristic { bluetooth_v2_shlib::Gatt::WriteType write_type, const std::vector& value, StatusCallback callback) override; - void Write(bluetooth_v2_shlib::Gatt::WriteType write_type, - const std::vector& value, + void Write(const std::vector& value, StatusCallback callback) override; bool NotificationEnabled() override; const bluetooth_v2_shlib::Gatt::Characteristic& characteristic() diff --git a/device/bluetooth/cast/bluetooth_device_cast.cc b/device/bluetooth/cast/bluetooth_device_cast.cc index 1dfeba9519739d..e92f3530ea8e37 100644 --- a/device/bluetooth/cast/bluetooth_device_cast.cc +++ b/device/bluetooth/cast/bluetooth_device_cast.cc @@ -57,6 +57,7 @@ BluetoothDeviceCast::BluetoothDeviceCast( BluetoothAdapter* adapter, scoped_refptr device) : BluetoothDevice(adapter), + connected_(device->IsConnected()), remote_device_(std::move(device)), address_(GetCanonicalBluetoothAddress(remote_device_->addr())), weak_factory_(this) {} diff --git a/device/bluetooth/cast/bluetooth_device_cast.h b/device/bluetooth/cast/bluetooth_device_cast.h index 562ba724dfa543..68ad822d411237 100644 --- a/device/bluetooth/cast/bluetooth_device_cast.h +++ b/device/bluetooth/cast/bluetooth_device_cast.h @@ -132,7 +132,7 @@ class BluetoothDeviceCast : public BluetoothDevice { // Called back from disconnect requests. void OnDisconnect(bool success); - bool connected_ = false; + bool connected_; bool pending_connect_ = false; bool pending_disconnect_ = false; diff --git a/device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.cc b/device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.cc index b0ae0d4b06ca57..3876ee9d5875e7 100644 --- a/device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.cc +++ b/device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.cc @@ -164,7 +164,6 @@ void BluetoothRemoteGattCharacteristicCast::WriteRemoteCharacteristic( const base::Closure& callback, const ErrorCallback& error_callback) { remote_characteristic_->Write( - chromecast::bluetooth_v2_shlib::Gatt::WriteType::WRITE_TYPE_DEFAULT, value, base::BindOnce( &BluetoothRemoteGattCharacteristicCast::OnWriteRemoteCharacteristic,