// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/run_loop.h"
#include "base/stl_util.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
#include "device/bluetooth/bluetooth_remote_gatt_service.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_ANDROID)
#include "device/bluetooth/test/bluetooth_test_android.h"
#elif defined(OS_MACOSX)
#include "device/bluetooth/test/bluetooth_test_mac.h"
#elif defined(OS_WIN)
#include "device/bluetooth/test/bluetooth_test_win.h"
#elif defined(USE_CAST_BLUETOOTH_ADAPTER)
#include "device/bluetooth/test/bluetooth_test_cast.h"
#elif defined(OS_CHROMEOS) || defined(OS_LINUX)
#include "device/bluetooth/test/bluetooth_test_bluez.h"
#elif defined(OS_FUCHSIA)
#include "device/bluetooth/test/bluetooth_test_fuchsia.h"
#endif

namespace device {

class BluetoothRemoteGattDescriptorTest :
#if defined(OS_WIN)
    public BluetoothTestWinrt {
#else
    public BluetoothTest {
#endif
 public:
  // Creates adapter_, device_, service_, characteristic_,
  // descriptor1_, & descriptor2_.
  void FakeDescriptorBoilerplate() {
    InitWithFakeAdapter();
    StartLowEnergyDiscoverySession();
    device_ = SimulateLowEnergyDevice(3);
    device_->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
                                  GetConnectErrorCallback(Call::NOT_EXPECTED));
    SimulateGattConnection(device_);
    base::RunLoop().RunUntilIdle();
    SimulateGattServicesDiscovered(
        device_, std::vector<std::string>({kTestUUIDGenericAccess}));
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(1u, device_->GetGattServices().size());
    service_ = device_->GetGattServices()[0];
    SimulateGattCharacteristic(service_, kTestUUIDDeviceName, 0);
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(1u, service_->GetCharacteristics().size());
    characteristic_ = service_->GetCharacteristics()[0];
    SimulateGattDescriptor(characteristic_,
                           kTestUUIDCharacteristicUserDescription);
    SimulateGattDescriptor(characteristic_,
                           kTestUUIDClientCharacteristicConfiguration);
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(2u, characteristic_->GetDescriptors().size());
    descriptor1_ = characteristic_->GetDescriptors()[0];
    descriptor2_ = characteristic_->GetDescriptors()[1];
    ResetEventCounts();
  }

  BluetoothDevice* device_ = nullptr;
  BluetoothRemoteGattService* service_ = nullptr;
  BluetoothRemoteGattCharacteristic* characteristic_ = nullptr;
  BluetoothRemoteGattDescriptor* descriptor1_ = nullptr;
  BluetoothRemoteGattDescriptor* descriptor2_ = nullptr;
};

#if defined(OS_WIN)
using BluetoothRemoteGattDescriptorTestWinrtOnly =
    BluetoothRemoteGattDescriptorTest;
#endif

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_GetIdentifier GetIdentifier
#else
#define MAYBE_GetIdentifier DISABLED_GetIdentifier
#endif
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly, GetIdentifier) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_GetIdentifier) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  InitWithFakeAdapter();
  StartLowEnergyDiscoverySession();
  // 2 devices to verify that descriptors on them have distinct IDs.
  BluetoothDevice* device1 = SimulateLowEnergyDevice(3);
  BluetoothDevice* device2 = SimulateLowEnergyDevice(4);
  device1->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
                                GetConnectErrorCallback(Call::NOT_EXPECTED));
  device2->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
                                GetConnectErrorCallback(Call::NOT_EXPECTED));
  SimulateGattConnection(device1);
  SimulateGattConnection(device2);
  base::RunLoop().RunUntilIdle();

  // 3 services (all with same UUID).
  //   1 on the first device (to test characteristic instances across devices).
  //   2 on the second device (to test same device, multiple service instances).
  SimulateGattServicesDiscovered(
      device1, std::vector<std::string>({kTestUUIDGenericAccess}));
  base::RunLoop().RunUntilIdle();
  SimulateGattServicesDiscovered(
      device2, std::vector<std::string>(
                   {kTestUUIDGenericAccess, kTestUUIDGenericAccess}));
  base::RunLoop().RunUntilIdle();
  BluetoothRemoteGattService* service1 = device1->GetGattServices()[0];
  BluetoothRemoteGattService* service2 = device2->GetGattServices()[0];
  BluetoothRemoteGattService* service3 = device2->GetGattServices()[1];
  // 6 characteristics (same UUID), 2 on each service.
  SimulateGattCharacteristic(service1, kTestUUIDDeviceName, /* properties */ 0);
  SimulateGattCharacteristic(service1, kTestUUIDDeviceName, /* properties */ 0);
  SimulateGattCharacteristic(service2, kTestUUIDDeviceName, /* properties */ 0);
  SimulateGattCharacteristic(service2, kTestUUIDDeviceName, /* properties */ 0);
  SimulateGattCharacteristic(service3, kTestUUIDDeviceName, /* properties */ 0);
  SimulateGattCharacteristic(service3, kTestUUIDDeviceName, /* properties */ 0);
  base::RunLoop().RunUntilIdle();
  BluetoothRemoteGattCharacteristic* char1 = service1->GetCharacteristics()[0];
  BluetoothRemoteGattCharacteristic* char2 = service1->GetCharacteristics()[1];
  BluetoothRemoteGattCharacteristic* char3 = service2->GetCharacteristics()[0];
  BluetoothRemoteGattCharacteristic* char4 = service2->GetCharacteristics()[1];
  BluetoothRemoteGattCharacteristic* char5 = service3->GetCharacteristics()[0];
  BluetoothRemoteGattCharacteristic* char6 = service3->GetCharacteristics()[1];
  // 6 descriptors (same UUID), 1 on each characteristic
  // TODO(576900) Test multiple descriptors with same UUID on one
  // characteristic.
  SimulateGattDescriptor(char1, kTestUUIDCharacteristicUserDescription);
  SimulateGattDescriptor(char2, kTestUUIDCharacteristicUserDescription);
  SimulateGattDescriptor(char3, kTestUUIDCharacteristicUserDescription);
  SimulateGattDescriptor(char4, kTestUUIDCharacteristicUserDescription);
  SimulateGattDescriptor(char5, kTestUUIDCharacteristicUserDescription);
  SimulateGattDescriptor(char6, kTestUUIDCharacteristicUserDescription);
  base::RunLoop().RunUntilIdle();
  BluetoothRemoteGattDescriptor* desc1 = char1->GetDescriptors()[0];
  BluetoothRemoteGattDescriptor* desc2 = char2->GetDescriptors()[0];
  BluetoothRemoteGattDescriptor* desc3 = char3->GetDescriptors()[0];
  BluetoothRemoteGattDescriptor* desc4 = char4->GetDescriptors()[0];
  BluetoothRemoteGattDescriptor* desc5 = char5->GetDescriptors()[0];
  BluetoothRemoteGattDescriptor* desc6 = char6->GetDescriptors()[0];

  // All IDs are unique.
  EXPECT_NE(desc1->GetIdentifier(), desc2->GetIdentifier());
  EXPECT_NE(desc1->GetIdentifier(), desc3->GetIdentifier());
  EXPECT_NE(desc1->GetIdentifier(), desc4->GetIdentifier());
  EXPECT_NE(desc1->GetIdentifier(), desc5->GetIdentifier());
  EXPECT_NE(desc1->GetIdentifier(), desc6->GetIdentifier());

  EXPECT_NE(desc2->GetIdentifier(), desc3->GetIdentifier());
  EXPECT_NE(desc2->GetIdentifier(), desc4->GetIdentifier());
  EXPECT_NE(desc2->GetIdentifier(), desc5->GetIdentifier());
  EXPECT_NE(desc2->GetIdentifier(), desc6->GetIdentifier());

  EXPECT_NE(desc3->GetIdentifier(), desc4->GetIdentifier());
  EXPECT_NE(desc3->GetIdentifier(), desc5->GetIdentifier());
  EXPECT_NE(desc3->GetIdentifier(), desc6->GetIdentifier());

  EXPECT_NE(desc4->GetIdentifier(), desc5->GetIdentifier());
  EXPECT_NE(desc4->GetIdentifier(), desc6->GetIdentifier());

  EXPECT_NE(desc5->GetIdentifier(), desc6->GetIdentifier());
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_GetUUID GetUUID
#else
#define MAYBE_GetUUID DISABLED_GetUUID
#endif
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly, GetUUID) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_GetUUID) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  InitWithFakeAdapter();
  StartLowEnergyDiscoverySession();
  BluetoothDevice* device = SimulateLowEnergyDevice(3);
  device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
                               GetConnectErrorCallback(Call::NOT_EXPECTED));
  SimulateGattConnection(device);
  SimulateGattServicesDiscovered(
      device, std::vector<std::string>({kTestUUIDGenericAccess}));
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(1u, device->GetGattServices().size());
  BluetoothRemoteGattService* service = device->GetGattServices()[0];

  SimulateGattCharacteristic(service, kTestUUIDDeviceName,
                             /* properties */ 0);
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(1u, service->GetCharacteristics().size());
  BluetoothRemoteGattCharacteristic* characteristic =
      service->GetCharacteristics()[0];

  // Create 2 descriptors.
  BluetoothUUID uuid1(kTestUUIDCharacteristicUserDescription);
  BluetoothUUID uuid2(kTestUUIDClientCharacteristicConfiguration);
  SimulateGattDescriptor(characteristic,
                         kTestUUIDCharacteristicUserDescription);
  SimulateGattDescriptor(characteristic,
                         kTestUUIDClientCharacteristicConfiguration);
  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(2u, characteristic->GetDescriptors().size());
  BluetoothRemoteGattDescriptor* descriptor1 =
      characteristic->GetDescriptors()[0];
  BluetoothRemoteGattDescriptor* descriptor2 =
      characteristic->GetDescriptors()[1];

  // Swap as needed to have descriptor1 be the one with uuid1.
  if (descriptor2->GetUUID() == uuid1)
    std::swap(descriptor1, descriptor2);

  EXPECT_EQ(uuid1, descriptor1->GetUUID());
  EXPECT_EQ(uuid2, descriptor2->GetUUID());
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_ReadRemoteDescriptor_Empty ReadRemoteDescriptor_Empty
#else
#define MAYBE_ReadRemoteDescriptor_Empty DISABLED_ReadRemoteDescriptor_Empty
#endif
// Tests ReadRemoteDescriptor and GetValue with empty value buffer.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly, ReadRemoteDescriptor_Empty) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_ReadRemoteDescriptor_Empty) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_read_descriptor_attempts_);
  std::vector<uint8_t> empty_vector;
  SimulateGattDescriptorRead(descriptor1_, empty_vector);
  base::RunLoop().RunUntilIdle();

  // Duplicate read reported from OS shouldn't cause a problem:
  SimulateGattDescriptorRead(descriptor1_, empty_vector);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(empty_vector, last_read_value_);
  EXPECT_EQ(empty_vector, descriptor1_->GetValue());
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_WriteRemoteDescriptor_Empty WriteRemoteDescriptor_Empty
#else
#define MAYBE_WriteRemoteDescriptor_Empty DISABLED_WriteRemoteDescriptor_Empty
#endif
// Tests WriteRemoteDescriptor with empty value buffer.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly,
       WriteRemoteDescriptor_Empty) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_WriteRemoteDescriptor_Empty) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  std::vector<uint8_t> empty_vector;
  descriptor1_->WriteRemoteDescriptor(empty_vector, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_write_descriptor_attempts_);
  SimulateGattDescriptorWrite(descriptor1_);
  base::RunLoop().RunUntilIdle();

  // Duplicate write reported from OS shouldn't cause a problem:
  SimulateGattDescriptorWrite(descriptor1_);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(empty_vector, last_write_value_);
}

#if defined(OS_ANDROID)
#define MAYBE_ReadRemoteDescriptor_AfterDeleted \
  ReadRemoteDescriptor_AfterDeleted
#else
#define MAYBE_ReadRemoteDescriptor_AfterDeleted \
  DISABLED_ReadRemoteDescriptor_AfterDeleted
#endif
// Tests ReadRemoteDescriptor completing after Chrome objects are deleted.
// macOS: Not applicable: This can never happen if CBPeripheral delegate is set
// to nil.
TEST_F(BluetoothRemoteGattDescriptorTest,
       MAYBE_ReadRemoteDescriptor_AfterDeleted) {
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::NOT_EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));

  RememberDescriptorForSubsequentAction(descriptor1_);
  DeleteDevice(device_);  // TODO(576906) delete only the descriptor.

  std::vector<uint8_t> empty_vector;
  SimulateGattDescriptorRead(/* use remembered descriptor */ nullptr,
                             empty_vector);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE("Did not crash!");
}

#if defined(OS_ANDROID)
#define MAYBE_WriteRemoteDescriptor_AfterDeleted \
  WriteRemoteDescriptor_AfterDeleted
#else
#define MAYBE_WriteRemoteDescriptor_AfterDeleted \
  DISABLED_WriteRemoteDescriptor_AfterDeleted
#endif
// Tests WriteRemoteDescriptor completing after Chrome objects are deleted.
// macOS: Not applicable: This can never happen if CBPeripheral delegate is set
// to nil.
TEST_F(BluetoothRemoteGattDescriptorTest,
       MAYBE_WriteRemoteDescriptor_AfterDeleted) {
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  std::vector<uint8_t> empty_vector;
  descriptor1_->WriteRemoteDescriptor(empty_vector,
                                      GetCallback(Call::NOT_EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));

  RememberDescriptorForSubsequentAction(descriptor1_);
  DeleteDevice(device_);  // TODO(576906) delete only the descriptor.

  SimulateGattDescriptorWrite(/* use remembered descriptor */ nullptr);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE("Did not crash!");
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_ReadRemoteDescriptor ReadRemoteDescriptor
#else
#define MAYBE_ReadRemoteDescriptor DISABLED_ReadRemoteDescriptor
#endif
// Tests ReadRemoteDescriptor and GetValue with non-empty value buffer.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly, ReadRemoteDescriptor) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_ReadRemoteDescriptor) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_read_descriptor_attempts_);

  uint8_t values[] = {0, 1, 2, 3, 4, 0xf, 0xf0, 0xff};
  std::vector<uint8_t> test_vector(values, values + base::size(values));
  SimulateGattDescriptorRead(descriptor1_, test_vector);
  base::RunLoop().RunUntilIdle();

  // Duplicate read reported from OS shouldn't cause a problem:
  std::vector<uint8_t> empty_vector;
  SimulateGattDescriptorRead(descriptor1_, empty_vector);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(test_vector, last_read_value_);
  EXPECT_EQ(test_vector, descriptor1_->GetValue());
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_WriteRemoteDescriptor WriteRemoteDescriptor
#else
#define MAYBE_WriteRemoteDescriptor DISABLED_WriteRemoteDescriptor
#endif
// Tests WriteRemoteDescriptor with non-empty value buffer.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly, WriteRemoteDescriptor) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_WriteRemoteDescriptor) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  uint8_t values[] = {0, 1, 2, 3, 4, 0xf, 0xf0, 0xff};
  std::vector<uint8_t> test_vector(values, values + base::size(values));
  descriptor1_->WriteRemoteDescriptor(test_vector, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_write_descriptor_attempts_);

  SimulateGattDescriptorWrite(descriptor1_);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(test_vector, last_write_value_);
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_ReadRemoteDescriptor_Twice ReadRemoteDescriptor_Twice
#else
#define MAYBE_ReadRemoteDescriptor_Twice DISABLED_ReadRemoteDescriptor_Twice
#endif
// Tests ReadRemoteDescriptor and GetValue multiple times.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly, ReadRemoteDescriptor_Twice) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_ReadRemoteDescriptor_Twice) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_read_descriptor_attempts_);

  uint8_t values[] = {0, 1, 2, 3, 4, 0xf, 0xf0, 0xff};
  std::vector<uint8_t> test_vector(values, values + base::size(values));
  SimulateGattDescriptorRead(descriptor1_, test_vector);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(test_vector, last_read_value_);
  EXPECT_EQ(test_vector, descriptor1_->GetValue());

  // Read again, with different value:
  ResetEventCounts();
  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_read_descriptor_attempts_);
  std::vector<uint8_t> empty_vector;
  SimulateGattDescriptorRead(descriptor1_, empty_vector);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(empty_vector, last_read_value_);
  EXPECT_EQ(empty_vector, descriptor1_->GetValue());
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_WriteRemoteDescriptor_Twice WriteRemoteDescriptor_Twice
#else
#define MAYBE_WriteRemoteDescriptor_Twice DISABLED_WriteRemoteDescriptor_Twice
#endif
// Tests WriteRemoteDescriptor multiple times.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly,
       WriteRemoteDescriptor_Twice) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_WriteRemoteDescriptor_Twice) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  uint8_t values[] = {0, 1, 2, 3, 4, 0xf, 0xf0, 0xff};
  std::vector<uint8_t> test_vector(values, values + base::size(values));
  descriptor1_->WriteRemoteDescriptor(test_vector, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_write_descriptor_attempts_);

  SimulateGattDescriptorWrite(descriptor1_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(test_vector, last_write_value_);

  // Write again, with different value:
  ResetEventCounts();
  std::vector<uint8_t> empty_vector;
  descriptor1_->WriteRemoteDescriptor(empty_vector, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_write_descriptor_attempts_);
  SimulateGattDescriptorWrite(descriptor1_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(empty_vector, last_write_value_);
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_ReadRemoteDescriptor_MultipleDescriptors \
  ReadRemoteDescriptor_MultipleDescriptors
#else
#define MAYBE_ReadRemoteDescriptor_MultipleDescriptors \
  DISABLED_ReadRemoteDescriptor_MultipleDescriptors
#endif
// Tests ReadRemoteDescriptor on two descriptors.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly,
       ReadRemoteDescriptor_MultipleDescriptors) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest,
       MAYBE_ReadRemoteDescriptor_MultipleDescriptors) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  descriptor2_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(2, gatt_read_descriptor_attempts_);
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  std::vector<uint8_t> test_vector1;
  test_vector1.push_back(111);
  SimulateGattDescriptorRead(descriptor1_, test_vector1);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(test_vector1, last_read_value_);

  std::vector<uint8_t> test_vector2;
  test_vector2.push_back(222);
  SimulateGattDescriptorRead(descriptor2_, test_vector2);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(test_vector2, last_read_value_);

  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_EQ(test_vector1, descriptor1_->GetValue());
  EXPECT_EQ(test_vector2, descriptor2_->GetValue());
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_WriteRemoteDescriptor_MultipleDescriptors \
  WriteRemoteDescriptor_MultipleDescriptors
#else
#define MAYBE_WriteRemoteDescriptor_MultipleDescriptors \
  DISABLED_WriteRemoteDescriptor_MultipleDescriptors
#endif
// Tests WriteRemoteDescriptor on two descriptors.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly,
       WriteRemoteDescriptor_MultipleDescriptors) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest,
       MAYBE_WriteRemoteDescriptor_MultipleDescriptors) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  std::vector<uint8_t> test_vector1;
  test_vector1.push_back(111);
  descriptor1_->WriteRemoteDescriptor(test_vector1, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(test_vector1, last_write_value_);

  std::vector<uint8_t> test_vector2;
  test_vector2.push_back(222);
  descriptor2_->WriteRemoteDescriptor(test_vector2, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(test_vector2, last_write_value_);

  EXPECT_EQ(2, gatt_write_descriptor_attempts_);
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(0, error_callback_count_);

  SimulateGattDescriptorWrite(descriptor1_);
  SimulateGattDescriptorWrite(descriptor2_);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(2, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_ReadError ReadError
#else
#define MAYBE_ReadError DISABLED_ReadError
#endif
// Tests ReadRemoteDescriptor asynchronous error.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly, ReadError) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_ReadError) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::NOT_EXPECTED),
                                     GetGattErrorCallback(Call::EXPECTED));
  SimulateGattDescriptorReadError(
      descriptor1_, BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH);
  SimulateGattDescriptorReadError(
      descriptor1_, BluetoothRemoteGattService::GATT_ERROR_FAILED);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH,
            last_gatt_error_code_);
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_WriteError WriteError
#else
#define MAYBE_WriteError DISABLED_WriteError
#endif
// Tests WriteRemoteDescriptor asynchronous error.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly, WriteError) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_WriteError) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  std::vector<uint8_t> empty_vector;
  descriptor1_->WriteRemoteDescriptor(empty_vector,
                                      GetCallback(Call::NOT_EXPECTED),
                                      GetGattErrorCallback(Call::EXPECTED));
  SimulateGattDescriptorWriteError(
      descriptor1_, BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH);
  SimulateGattDescriptorWriteError(
      descriptor1_, BluetoothRemoteGattService::GATT_ERROR_FAILED);
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_INVALID_LENGTH,
            last_gatt_error_code_);
}

#if defined(OS_ANDROID)
#define MAYBE_ReadSynchronousError ReadSynchronousError
#else
#define MAYBE_ReadSynchronousError DISABLED_ReadSynchronousError
#endif
// Tests ReadRemoteDescriptor synchronous error.
// Test not relevant for macOS since descriptor read cannot generate
// synchronous error.
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_ReadSynchronousError) {
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  SimulateGattDescriptorReadWillFailSynchronouslyOnce(descriptor1_);
  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::NOT_EXPECTED),
                                     GetGattErrorCallback(Call::EXPECTED));
  EXPECT_EQ(0, gatt_read_descriptor_attempts_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED,
            last_gatt_error_code_);

  // After failing once, can succeed:
  ResetEventCounts();
  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_read_descriptor_attempts_);
  std::vector<uint8_t> empty_vector;
  SimulateGattDescriptorRead(descriptor1_, empty_vector);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

#if defined(OS_ANDROID)
#define MAYBE_WriteSynchronousError WriteSynchronousError
#else
#define MAYBE_WriteSynchronousError DISABLED_WriteSynchronousError
#endif
// Tests WriteRemoteDescriptor synchronous error.
// Test not relevant for macOS since descriptor write cannot generate
// synchronous error.
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_WriteSynchronousError) {
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  SimulateGattDescriptorWriteWillFailSynchronouslyOnce(descriptor1_);
  std::vector<uint8_t> empty_vector;
  descriptor1_->WriteRemoteDescriptor(empty_vector,
                                      GetCallback(Call::NOT_EXPECTED),
                                      GetGattErrorCallback(Call::EXPECTED));
  EXPECT_EQ(0, gatt_write_descriptor_attempts_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_FAILED,
            last_gatt_error_code_);

  // After failing once, can succeed:
  ResetEventCounts();
  descriptor1_->WriteRemoteDescriptor(empty_vector, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_write_descriptor_attempts_);
  SimulateGattDescriptorWrite(descriptor1_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_ReadRemoteDescriptor_ReadPending ReadRemoteDescriptor_ReadPending
#else
#define MAYBE_ReadRemoteDescriptor_ReadPending \
  DISABLED_ReadRemoteDescriptor_ReadPending
#endif
// Tests ReadRemoteDescriptor error with a pending read operation.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly,
       ReadRemoteDescriptor_ReadPending) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest,
       MAYBE_ReadRemoteDescriptor_ReadPending) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::NOT_EXPECTED),
                                     GetGattErrorCallback(Call::EXPECTED));

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS,
            last_gatt_error_code_);

  // Initial read should still succeed:
  ResetEventCounts();
  std::vector<uint8_t> empty_vector;
  SimulateGattDescriptorRead(descriptor1_, empty_vector);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_WriteRemoteDescriptor_WritePending \
  WriteRemoteDescriptor_WritePending
#else
#define MAYBE_WriteRemoteDescriptor_WritePending \
  DISABLED_WriteRemoteDescriptor_WritePending
#endif
// Tests WriteRemoteDescriptor error with a pending write operation.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly,
       WriteRemoteDescriptor_WritePending) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest,
       MAYBE_WriteRemoteDescriptor_WritePending) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  std::vector<uint8_t> empty_vector;
  descriptor1_->WriteRemoteDescriptor(empty_vector, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  descriptor1_->WriteRemoteDescriptor(empty_vector,
                                      GetCallback(Call::NOT_EXPECTED),
                                      GetGattErrorCallback(Call::EXPECTED));

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS,
            last_gatt_error_code_);

  // Initial write should still succeed:
  ResetEventCounts();
  SimulateGattDescriptorWrite(descriptor1_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_ReadRemoteDescriptor_WritePending \
  ReadRemoteDescriptor_WritePending
#else
#define MAYBE_ReadRemoteDescriptor_WritePending \
  DISABLED_ReadRemoteDescriptor_WritePending
#endif
// Tests ReadRemoteDescriptor error with a pending write operation.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly,
       ReadRemoteDescriptor_WritePending) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest,
       MAYBE_ReadRemoteDescriptor_WritePending) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  std::vector<uint8_t> empty_vector;
  descriptor1_->WriteRemoteDescriptor(empty_vector, GetCallback(Call::EXPECTED),
                                      GetGattErrorCallback(Call::NOT_EXPECTED));
  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::NOT_EXPECTED),
                                     GetGattErrorCallback(Call::EXPECTED));

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS,
            last_gatt_error_code_);

  // Initial write should still succeed:
  ResetEventCounts();
  SimulateGattDescriptorWrite(descriptor1_);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

#if defined(OS_ANDROID) || defined(OS_MACOSX)
#define MAYBE_WriteRemoteDescriptor_ReadPending \
  WriteRemoteDescriptor_ReadPending
#else
#define MAYBE_WriteRemoteDescriptor_ReadPending \
  DISABLED_WriteRemoteDescriptor_ReadPending
#endif
// Tests WriteRemoteDescriptor error with a pending Read operation.
#if defined(OS_WIN)
TEST_P(BluetoothRemoteGattDescriptorTestWinrtOnly,
       WriteRemoteDescriptor_ReadPending) {
#else
TEST_F(BluetoothRemoteGattDescriptorTest,
       MAYBE_WriteRemoteDescriptor_ReadPending) {
#endif
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  std::vector<uint8_t> empty_vector;
  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  descriptor1_->WriteRemoteDescriptor(empty_vector,
                                      GetCallback(Call::NOT_EXPECTED),
                                      GetGattErrorCallback(Call::EXPECTED));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_EQ(BluetoothRemoteGattService::GATT_ERROR_IN_PROGRESS,
            last_gatt_error_code_);

  // Initial read should still succeed:
  ResetEventCounts();
  SimulateGattDescriptorRead(descriptor1_, empty_vector);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
}

#if defined(OS_ANDROID)
#define MAYBE_ReadDuringDisconnect ReadDuringDisconnect
#else
#define MAYBE_ReadDuringDisconnect DISABLED_ReadDuringDisconnect
#endif
// Tests that read requests after a device disconnects but before the
// disconnect task runs do not result in a crash.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/694102): Enable this test on Windows.
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_ReadDuringDisconnect) {
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }

  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  SimulateGattDisconnection(device_);
  // Don't run the disconnect task.
  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::NOT_EXPECTED),
                                     // TODO(crbug.com/621901): Expect an error.
                                     GetGattErrorCallback(Call::NOT_EXPECTED));

  base::RunLoop().RunUntilIdle();
  // TODO(crbug.com/621901): Test error callback was called.
}

#if defined(OS_ANDROID)
#define MAYBE_WriteDuringDisconnect WriteDuringDisconnect
#else
#define MAYBE_WriteDuringDisconnect DISABLED_WriteDuringDisconnect
#endif
// Tests that write requests after a device disconnects but before the
// disconnect task runs do not result in a crash.
// macOS: Does not apply. All events arrive on the UI Thread.
// TODO(crbug.com/694102): Enable this test on Windows.
TEST_F(BluetoothRemoteGattDescriptorTest, MAYBE_WriteDuringDisconnect) {
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }

  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  SimulateGattDisconnection(device_);
  // Don't run the disconnect task.
  descriptor1_->WriteRemoteDescriptor(
      std::vector<uint8_t>(), GetCallback(Call::NOT_EXPECTED),
      // TODO(crbug.com/621901): Expect an error.
      GetGattErrorCallback(Call::NOT_EXPECTED));

  base::RunLoop().RunUntilIdle();
  // TODO(crbug.com/621901): Test that an error was returned.
}

#if defined(OS_MACOSX)
// Tests NSString for descriptor value for macOS.
// https://developer.apple.com/reference/corebluetooth/cbdescriptor
TEST_F(BluetoothRemoteGattDescriptorTest, ReadRemoteDescriptor_NSString) {
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_read_descriptor_attempts_);

  std::string test_string = "Hello";
  SimulateGattDescriptorReadNSStringMac(descriptor1_, test_string);
  base::RunLoop().RunUntilIdle();

  std::vector<uint8_t> test_vector(test_string.begin(), test_string.end());
  EXPECT_EQ(test_vector, last_read_value_);
  EXPECT_EQ(test_vector, descriptor1_->GetValue());
}

// Tests NSNumber for descriptor value for macOS.
// https://developer.apple.com/reference/corebluetooth/cbdescriptor
TEST_F(BluetoothRemoteGattDescriptorTest, ReadRemoteDescriptor_NSNumber) {
  if (!PlatformSupportsLowEnergy()) {
    LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
    return;
  }
  ASSERT_NO_FATAL_FAILURE(FakeDescriptorBoilerplate());

  descriptor1_->ReadRemoteDescriptor(GetReadValueCallback(Call::EXPECTED),
                                     GetGattErrorCallback(Call::NOT_EXPECTED));
  EXPECT_EQ(1, gatt_read_descriptor_attempts_);

  const short test_number = 0x1234;
  SimulateGattDescriptorReadNSNumberMac(descriptor1_, test_number);
  base::RunLoop().RunUntilIdle();

  uint8_t values[] = {0x34, 0x12};
  std::vector<uint8_t> test_vector(values, values + base::size(values));
  EXPECT_EQ(test_vector, last_read_value_);
  EXPECT_EQ(test_vector, descriptor1_->GetValue());
}
#endif  // defined(OS_MACOSX)

#if defined(OS_WIN)
INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    BluetoothRemoteGattDescriptorTestWinrtOnly,
    ::testing::Values(true));
#endif  // defined(OS_WIN)

}  // namespace device
