| Index: components/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
|
| diff --git a/components/arc/bluetooth/arc_bluetooth_bridge_unittest.cc b/components/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
|
| index 62f984996eadfb88a931bd74b978d8a4f2a6de92..23041dfd22170f16fc4a1f6775af9b1d3b2a4ff3 100644
|
| --- a/components/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
|
| +++ b/components/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
|
| @@ -21,11 +21,14 @@
|
| #include "device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h"
|
| #include "device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h"
|
| #include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
|
| +#include "device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h"
|
| #include "mojo/public/cpp/bindings/array.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace arc {
|
|
|
| +constexpr int kFailureAdvHandle = -1;
|
| +
|
| class ArcBluetoothBridgeTest : public testing::Test {
|
| protected:
|
| void AddTestDevice() {
|
| @@ -82,6 +85,70 @@ class ArcBluetoothBridgeTest : public testing::Test {
|
| get_adapter_run_loop_.Run();
|
| }
|
|
|
| + // Helper methods for multi advertisement tests.
|
| + int32_t ReserveAdvertisementHandle() {
|
| + constexpr int kSentinelHandle = -2;
|
| + last_adv_handle_ = kSentinelHandle;
|
| + arc_bluetooth_bridge_->ReserveAdvertisementHandle(
|
| + base::Bind(&ArcBluetoothBridgeTest::ReserveAdvertisementHandleCallback,
|
| + base::Unretained(this)));
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| + // Make sure the callback was called.
|
| + EXPECT_NE(kSentinelHandle, last_adv_handle_);
|
| + return last_adv_handle_;
|
| + }
|
| +
|
| + mojom::BluetoothGattStatus BroadcastAdvertisement(
|
| + int adv_handle,
|
| + std::unique_ptr<device::BluetoothAdvertisement::Data> data) {
|
| + last_status_ = mojom::BluetoothGattStatus::GATT_REQUEST_NOT_SUPPORTED;
|
| + arc_bluetooth_bridge_->BroadcastAdvertisement(
|
| + adv_handle, std::move(data),
|
| + base::Bind(&ArcBluetoothBridgeTest::StatusSetterCallback,
|
| + base::Unretained(this)));
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_NE(mojom::BluetoothGattStatus::GATT_REQUEST_NOT_SUPPORTED,
|
| + last_status_);
|
| + return last_status_;
|
| + }
|
| +
|
| + mojom::BluetoothGattStatus ReleaseAdvertisementHandle(int adv_handle) {
|
| + last_status_ = mojom::BluetoothGattStatus::GATT_REQUEST_NOT_SUPPORTED;
|
| + arc_bluetooth_bridge_->ReleaseAdvertisementHandle(
|
| + adv_handle, base::Bind(&ArcBluetoothBridgeTest::StatusSetterCallback,
|
| + base::Unretained(this)));
|
| +
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_NE(mojom::BluetoothGattStatus::GATT_REQUEST_NOT_SUPPORTED,
|
| + last_status_);
|
| + return last_status_;
|
| + }
|
| +
|
| + void ReserveAdvertisementHandleCallback(mojom::BluetoothGattStatus status,
|
| + int32_t adv_handle) {
|
| + if (status == mojom::BluetoothGattStatus::GATT_FAILURE)
|
| + last_adv_handle_ = kFailureAdvHandle;
|
| + else
|
| + last_adv_handle_ = adv_handle;
|
| + }
|
| +
|
| + void StatusSetterCallback(mojom::BluetoothGattStatus status) {
|
| + last_status_ = status;
|
| + }
|
| +
|
| + int NumActiveAdvertisements() {
|
| + bluez::FakeBluetoothLEAdvertisingManagerClient* adv_client =
|
| + static_cast<bluez::FakeBluetoothLEAdvertisingManagerClient*>(
|
| + bluez::BluezDBusManager::Get()
|
| + ->GetBluetoothLEAdvertisingManagerClient());
|
| + return adv_client->currently_registered();
|
| + }
|
| +
|
| + int last_adv_handle_;
|
| + mojom::BluetoothGattStatus last_status_;
|
| +
|
| std::unique_ptr<FakeArcBridgeService> fake_arc_bridge_service_;
|
| std::unique_ptr<FakeBluetoothInstance> fake_bluetooth_instance_;
|
| std::unique_ptr<ArcBluetoothBridge> arc_bluetooth_bridge_;
|
| @@ -211,4 +278,78 @@ TEST_F(ArcBluetoothBridgeTest, GetGattDB) {
|
| db[4]->properties);
|
| }
|
|
|
| +// Invoke multi advertisement methods and make sure they are going down to the
|
| +// D-Bus clients.
|
| +TEST_F(ArcBluetoothBridgeTest, SingleAdvertisement) {
|
| + int32_t handle = ReserveAdvertisementHandle();
|
| + EXPECT_NE(kFailureAdvHandle, handle);
|
| + EXPECT_EQ(0, NumActiveAdvertisements());
|
| +
|
| + auto adv_data = base::MakeUnique<device::BluetoothAdvertisement::Data>(
|
| + device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
|
| + mojom::BluetoothGattStatus status =
|
| + BroadcastAdvertisement(handle, std::move(adv_data));
|
| + EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status);
|
| + EXPECT_EQ(1, NumActiveAdvertisements());
|
| +
|
| + status = ReleaseAdvertisementHandle(handle);
|
| + EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status);
|
| + EXPECT_EQ(0, NumActiveAdvertisements());
|
| +}
|
| +
|
| +// Invoke multi advertisement methods and make sure they are going down to the
|
| +// D-Bus clients.
|
| +TEST_F(ArcBluetoothBridgeTest, MultiAdvertisement) {
|
| + int32_t handle = ReserveAdvertisementHandle();
|
| + EXPECT_NE(kFailureAdvHandle, handle);
|
| + EXPECT_EQ(0, NumActiveAdvertisements());
|
| +
|
| + auto adv_data = base::MakeUnique<device::BluetoothAdvertisement::Data>(
|
| + device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
|
| + mojom::BluetoothGattStatus status =
|
| + BroadcastAdvertisement(handle, std::move(adv_data));
|
| + EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status);
|
| + EXPECT_EQ(1, NumActiveAdvertisements());
|
| +
|
| + int32_t handle2 = ReserveAdvertisementHandle();
|
| + EXPECT_NE(kFailureAdvHandle, handle2);
|
| + auto adv_data2 = base::MakeUnique<device::BluetoothAdvertisement::Data>(
|
| + device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_PERIPHERAL);
|
| + status = BroadcastAdvertisement(handle2, std::move(adv_data2));
|
| + EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status);
|
| + EXPECT_EQ(2, NumActiveAdvertisements());
|
| +
|
| + status = ReleaseAdvertisementHandle(handle);
|
| + EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status);
|
| + EXPECT_EQ(1, NumActiveAdvertisements());
|
| +
|
| + status = ReleaseAdvertisementHandle(handle2);
|
| + EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status);
|
| + EXPECT_EQ(0, NumActiveAdvertisements());
|
| +}
|
| +
|
| +// This tests that we support releasing reserved but unused handles.
|
| +// TODO(ejcaruso): When Chrome supports more handles, make sure we
|
| +// will stop reserving handles before we use all of Chrome's.
|
| +TEST_F(ArcBluetoothBridgeTest, ReleaseUnusedHandles) {
|
| + constexpr size_t kMaxBluezAdvertisements =
|
| + bluez::FakeBluetoothLEAdvertisingManagerClient::kMaxBluezAdvertisements;
|
| + std::vector<int32_t> reserved_handles;
|
| +
|
| + for (size_t i = 0; i < kMaxBluezAdvertisements; i++) {
|
| + int32_t handle = ReserveAdvertisementHandle();
|
| + if (handle == kFailureAdvHandle)
|
| + break;
|
| + reserved_handles.push_back(handle);
|
| + }
|
| + EXPECT_GT(reserved_handles.size(), 1Ul);
|
| + EXPECT_LE(reserved_handles.size(), kMaxBluezAdvertisements);
|
| + EXPECT_EQ(0, NumActiveAdvertisements());
|
| +
|
| + for (int32_t handle : reserved_handles) {
|
| + EXPECT_EQ(ReleaseAdvertisementHandle(handle),
|
| + mojom::BluetoothGattStatus::GATT_SUCCESS);
|
| + }
|
| +}
|
| +
|
| } // namespace arc
|
|
|