chromium/device/bluetooth/bluetooth_adapter_unittest.cc

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

#include "device/bluetooth/bluetooth_adapter.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/barrier_closure.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/bind.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "device/bluetooth/bluetooth_common.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_discovery_session.h"
#include "device/bluetooth/bluetooth_gatt_service.h"
#include "device/bluetooth/bluetooth_local_gatt_characteristic.h"
#include "device/bluetooth/bluetooth_local_gatt_descriptor.h"
#include "device/bluetooth/bluetooth_local_gatt_service.h"
#include "device/bluetooth/test/bluetooth_test.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "device/bluetooth/test/test_bluetooth_advertisement_observer.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if BUILDFLAG(IS_ANDROID)
#include "device/bluetooth/test/bluetooth_test_android.h"
#elif BUILDFLAG(IS_APPLE)
#include "device/bluetooth/test/bluetooth_test_mac.h"
#elif BUILDFLAG(IS_WIN)
#include "base/win/windows_version.h"
#include "device/bluetooth/test/bluetooth_test_win.h"
#elif defined(USE_CAST_BLUETOOTH_ADAPTER)
#include "device/bluetooth/test/bluetooth_test_cast.h"
#elif BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
#include "device/bluetooth/test/bluetooth_test_bluez.h"
#elif BUILDFLAG(IS_FUCHSIA)
#include "device/bluetooth/test/bluetooth_test_fuchsia.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "device/bluetooth/bluetooth_low_energy_scan_filter.h"
#include "device/bluetooth/bluetooth_low_energy_scan_session.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

BluetoothDevice;

namespace device {

void AddDeviceFilterWithUUID(BluetoothDiscoveryFilter* filter,
                             BluetoothUUID uuid) {}

namespace {

class TestBluetoothAdapter final : public BluetoothAdapter {};

class TestPairingDelegate : public BluetoothDevice::PairingDelegate {};

bool ServiceSetsEqual(
    std::vector<BluetoothLocalGattService*> services,
    std::initializer_list<BluetoothLocalGattService*> services_to_check) {}

}  // namespace

class BluetoothAdapterTest : public testing::Test {};

TEST_F(BluetoothAdapterTest, NoDefaultPairingDelegate) {}

TEST_F(BluetoothAdapterTest, OneDefaultPairingDelegate) {}

TEST_F(BluetoothAdapterTest, SamePriorityDelegates) {}

TEST_F(BluetoothAdapterTest, HighestPriorityDelegate) {}

TEST_F(BluetoothAdapterTest, UnregisterDelegate) {}

TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterEmpty) {}

TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterRegular) {}

TEST_F(BluetoothAdapterTest, TestQueueingLogic) {}

TEST_F(BluetoothAdapterTest, ShortCircuitUpdateTest) {}

TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterRssi) {}

TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterTransport) {}

TEST_F(BluetoothAdapterTest, GetMergedDiscoveryFilterAllFields) {}

TEST_F(BluetoothAdapterTest, StartDiscoverySession_Destroy) {}

TEST_F(BluetoothAdapterTest, StartDiscoverySessionError_Destroy) {}

// TODO(scheib): Enable BluetoothTest fixture tests on all platforms.
// TODO(https://crbug.com/331653043): Re-enable when passing on macOS 14 bots.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_ConstructDefaultAdapter
#else
#define MAYBE_ConstructDefaultAdapter
#endif

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, ConstructDefaultAdapter) {
#else
TEST_F(BluetoothTest, MAYBE_ConstructDefaultAdapter) {}  // namespace device

// TODO(scheib): Enable BluetoothTest fixture tests on all platforms.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ConstructWithoutDefaultAdapter
#else
#define MAYBE_ConstructWithoutDefaultAdapter
#endif

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, ConstructWithoutDefaultAdapter) {
#else
TEST_F(BluetoothTest, MAYBE_ConstructWithoutDefaultAdapter) {}

// TODO(scheib): Enable BluetoothTest fixture tests on all platforms.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_ConstructFakeAdapter
#else
#define MAYBE_ConstructFakeAdapter
#endif

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, ConstructFakeAdapter) {
#else
TEST_F(BluetoothTest, MAYBE_ConstructFakeAdapter) {}

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, ConstructFakeAdapterWithoutRadio) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitFakeAdapterWithoutRadio();
  EXPECT_EQ(adapter_->GetAddress(), kTestAdapterAddress);
  EXPECT_EQ(adapter_->GetName(), kTestAdapterName);
  EXPECT_TRUE(adapter_->IsPresent());
  EXPECT_FALSE(adapter_->CanPower());
  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_FALSE(adapter_->IsDiscoverable());
  EXPECT_FALSE(adapter_->IsDiscovering());
}

TEST_P(BluetoothTestWinrt, ConstructFakeAdapterWithoutPowerControl) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitFakeAdapterWithRadioAccessDenied();
  EXPECT_EQ(adapter_->GetAddress(), kTestAdapterAddress);
  EXPECT_EQ(adapter_->GetName(), kTestAdapterName);
  EXPECT_TRUE(adapter_->IsPresent());
  EXPECT_FALSE(adapter_->CanPower());
  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_FALSE(adapter_->IsDiscoverable());
  EXPECT_FALSE(adapter_->IsDiscovering());
}
#endif  // BUILDFLAG(IS_WIN)

// TODO(scheib): Enable BluetoothTest fixture tests on all platforms.
#if BUILDFLAG(IS_ANDROID)
#define MAYBE_DiscoverySession
#else
#define MAYBE_DiscoverySession
#endif
// Starts and Stops a discovery session.
TEST_F(BluetoothTest, MAYBE_DiscoverySession) {}

// Android only: this test is specific for Android and should not be
// enabled for other platforms.
#if BUILDFLAG(IS_ANDROID)
TEST_F(BluetoothTest, AdapterIllegalStateBeforeStartScan) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }
  InitWithFakeAdapter();
  ForceIllegalStateException();
  StartLowEnergyDiscoverySessionExpectedToFail();
  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
  EXPECT_FALSE(adapter_->IsDiscovering());
}
#endif  // BUILDFLAG(IS_ANDROID)

// Android only: this test is specific for Android and should not be
// enabled for other platforms.
#if BUILDFLAG(IS_ANDROID)
TEST_F(BluetoothTest, AdapterIllegalStateBeforeStopScan) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }
  InitWithFakeAdapter();
  StartLowEnergyDiscoverySession();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsDiscovering());
  ForceIllegalStateException();
  discovery_sessions_[0]->Stop(GetCallback(Call::EXPECTED),
                               GetErrorCallback(Call::NOT_EXPECTED));
  EXPECT_FALSE(adapter_->IsDiscovering());
}
#endif  // BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_NoPermissions
#else
#define MAYBE_NoPermissions
#endif
// Checks that discovery fails (instead of hanging) when permissions are denied.
TEST_F(BluetoothTest, MAYBE_NoPermissions) {}

// Android-only: Only Android requires location services to be turned on to scan
// for Bluetooth devices.
#if BUILDFLAG(IS_ANDROID)
// Checks that discovery fails (instead of hanging) when location services are
// turned off.
TEST_F(BluetoothTest, NoLocationServices) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }
  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);

  SimulateLocationServicesOff();

  StartLowEnergyDiscoverySessionExpectedToFail();

  EXPECT_EQ(0, callback_count_);
  EXPECT_EQ(1, error_callback_count_);
}
#endif  // BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DiscoverLowEnergyDevice
#else
#define MAYBE_DiscoverLowEnergyDevice
#endif
// Discovers a device.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverLowEnergyDevice) {
#else
TEST_F(BluetoothTest, MAYBE_DiscoverLowEnergyDevice) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DiscoverLowEnergyDeviceTwice
#else
#define MAYBE_DiscoverLowEnergyDeviceTwice
#endif
// Discovers the same device multiple times.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverLowEnergyDeviceTwice) {
#else
TEST_F(BluetoothTest, MAYBE_DiscoverLowEnergyDeviceTwice) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DiscoverLowEnergyDeviceWithUpdatedUUIDs
#else
#define MAYBE_DiscoverLowEnergyDeviceWithUpdatedUUIDs
#endif
// Discovers a device, and then again with new Service UUIDs.
// Makes sure we don't create another device when we've found the
// device in the past.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverLowEnergyDeviceWithUpdatedUUIDs) {
#else
TEST_F(BluetoothTest, MAYBE_DiscoverLowEnergyDeviceWithUpdatedUUIDs) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_DiscoverMultipleLowEnergyDevices
#else
#define MAYBE_DiscoverMultipleLowEnergyDevices
#endif
// Discovers multiple devices when addresses vary.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverMultipleLowEnergyDevices) {
#else
TEST_F(BluetoothTest, MAYBE_DiscoverMultipleLowEnergyDevices) {}

#if BUILDFLAG(IS_WIN)
// Tests that the adapter responds to external changes to the power state.
TEST_P(BluetoothTestWinrt, SimulateAdapterPoweredOffAndOn) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);

  ASSERT_TRUE(adapter_->IsPresent());
  ASSERT_TRUE(adapter_->IsPowered());
  EXPECT_EQ(0, observer.powered_changed_count());

  SimulateAdapterPoweredOff();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_EQ(1, observer.powered_changed_count());
  EXPECT_FALSE(observer.last_powered());

  SimulateAdapterPoweredOn();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_EQ(2, observer.powered_changed_count());
  EXPECT_TRUE(observer.last_powered());
}

// Tests that power change notifications are deduplicated.
// Multiple StateChanged events with the same state only cause a
// single AdapterPoweredChanged() call.
TEST_P(BluetoothTestWinrt, SimulateDuplicateStateChanged) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);

  ASSERT_TRUE(adapter_->IsPresent());
  ASSERT_TRUE(adapter_->IsPowered());
  EXPECT_EQ(0, observer.powered_changed_count());

  SimulateSpuriousRadioStateChangedEvent();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_EQ(0, observer.powered_changed_count());

  SimulateAdapterPoweredOff();
  SimulateSpuriousRadioStateChangedEvent();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_EQ(1, observer.powered_changed_count());
  EXPECT_FALSE(observer.last_powered());

  SimulateAdapterPoweredOn();
  SimulateSpuriousRadioStateChangedEvent();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_EQ(2, observer.powered_changed_count());
  EXPECT_TRUE(observer.last_powered());
}

// Tests that the adapter responds to external changes to the power state, even
// if it failed to obtain the underlying radio.
TEST_P(BluetoothTestWinrt, SimulateAdapterPoweredOnAndOffWithoutRadio) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitFakeAdapterWithoutRadio();
  TestBluetoothAdapterObserver observer(adapter_);

  ASSERT_TRUE(adapter_->IsPresent());
  ASSERT_FALSE(adapter_->IsPowered());
  EXPECT_EQ(0, observer.powered_changed_count());

  SimulateAdapterPoweredOn();
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(adapter_->IsPowered());
  EXPECT_EQ(1, observer.powered_changed_count());
  EXPECT_TRUE(observer.last_powered());

  SimulateAdapterPoweredOff();
  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(adapter_->IsPowered());
  EXPECT_EQ(2, observer.powered_changed_count());
  EXPECT_FALSE(observer.last_powered());
}

// Makes sure the error callback gets run when changing the adapter power state
// fails.
// TODO(crbug.com/41410591): Implement SimulateAdapterPowerSuccess() and
// enable on all platforms.
TEST_P(BluetoothTestWinrt, SimulateAdapterPowerFailure) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitWithFakeAdapter();
  ASSERT_TRUE(adapter_->IsPresent());
  ASSERT_TRUE(adapter_->IsPowered());

  adapter_->SetPowered(false, GetCallback(Call::NOT_EXPECTED),
                       GetErrorCallback(Call::EXPECTED));
  SimulateAdapterPowerFailure();
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(adapter_->IsPowered());
}
#endif  // BUILDFLAG(IS_WIN)

// TODO(crbug.com/41366193): Enable this test on old Windows versions as
// well.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter) {
#else
#if BUILDFLAG(IS_IOS)
#define MAYBE_TogglePowerFakeAdapter
#else
#define MAYBE_TogglePowerFakeAdapter
#endif
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TogglePowerFakeAdapter_Twice
#else
#define MAYBE_TogglePowerFakeAdapter_Twice
#endif
// These tests are not relevant for BlueZ and old Windows versions. On these
// platforms the corresponding system APIs are blocking or use callbacks, so
// that it is not necessary to store pending callbacks and wait for the
// appropriate events.
#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter_Twice) {
#else
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter_Twice) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TogglePowerFakeAdapter_WithinCallback_On_Off
#else
#define MAYBE_TogglePowerFakeAdapter_WithinCallback_On_Off
#endif

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter_WithinCallback_On_Off) {
#else
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter_WithinCallback_On_Off) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TogglePowerFakeAdapter_WithinCallback_Off_On
#else
#define MAYBE_TogglePowerFakeAdapter_WithinCallback_Off_On
#endif

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter_WithinCallback_Off_On) {
#else
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter_WithinCallback_Off_On) {}

#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_MAC)
#define MAYBE_TogglePowerFakeAdapter_DestroyWithPending
#else
#define MAYBE_TogglePowerFakeAdapter_DestroyWithPending
#endif

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, TogglePowerFakeAdapter_DestroyWithPending) {
#else
TEST_F(BluetoothTest, MAYBE_TogglePowerFakeAdapter_DestroyWithPending) {}

#if BUILDFLAG(IS_ANDROID)
#define MAYBE_TogglePowerBeforeScan
#else
#define MAYBE_TogglePowerBeforeScan
#endif
TEST_F(BluetoothTest, MAYBE_TogglePowerBeforeScan) {}

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, DiscoverySessionFailure) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);
  EXPECT_FALSE(adapter_->IsDiscovering());

  StartLowEnergyDiscoverySession();
  EXPECT_EQ(1, callback_count_);
  EXPECT_EQ(0, error_callback_count_);
  EXPECT_TRUE(adapter_->IsDiscovering());
  EXPECT_EQ(1, observer.discovering_changed_count());
  EXPECT_TRUE(observer.last_discovering());
  ASSERT_EQ((size_t)1, discovery_sessions_.size());
  EXPECT_TRUE(discovery_sessions_[0]->IsActive());

  SimulateLowEnergyDiscoveryFailure();
  EXPECT_FALSE(adapter_->IsDiscovering());
  EXPECT_FALSE(discovery_sessions_[0]->IsActive());
  EXPECT_EQ(2, observer.discovering_changed_count());
  EXPECT_FALSE(observer.last_discovering());
}
#endif  // BUILDFLAG(IS_WIN)

#if BUILDFLAG(IS_MAC)
#define MAYBE_TurnOffAdapterWithConnectedDevice
#else
#define MAYBE_TurnOffAdapterWithConnectedDevice
#endif
// TODO(crbug.com/40522060): Enable on relevant platforms.
TEST_F(BluetoothTest, MAYBE_TurnOffAdapterWithConnectedDevice) {}

#if BUILDFLAG(IS_WIN)
TEST_P(BluetoothTestWinrt, RegisterAdvertisement) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
      BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
  advertisement_data->set_manufacturer_data(
      BluetoothAdvertisement::ManufacturerData());

  InitWithFakeAdapter();
  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      GetCreateAdvertisementCallback(Call::EXPECTED),
      GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
  auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
  ASSERT_FALSE(pending_advertisements.empty());
  SimulateAdvertisementStarted(pending_advertisements[0]);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}

TEST_P(BluetoothTestWinrt, FailRegisterAdvertisement) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
      BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
  advertisement_data->set_manufacturer_data(
      BluetoothAdvertisement::ManufacturerData());

  InitWithFakeAdapter();
  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      GetCreateAdvertisementCallback(Call::NOT_EXPECTED),
      GetAdvertisementErrorCallback(Call::EXPECTED));
  auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
  ASSERT_FALSE(pending_advertisements.empty());
  SimulateAdvertisementError(pending_advertisements[0],
                             BluetoothAdvertisement::ERROR_ADAPTER_POWERED_OFF);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(BluetoothAdvertisement::ERROR_ADAPTER_POWERED_OFF,
            last_advertisement_error_code_);
  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}

TEST_P(BluetoothTestWinrt, RegisterAndUnregisterAdvertisement) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
      BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
  advertisement_data->set_manufacturer_data(
      BluetoothAdvertisement::ManufacturerData());

  InitWithFakeAdapter();
  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      GetCreateAdvertisementCallback(Call::EXPECTED),
      GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
  auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
  ASSERT_FALSE(pending_advertisements.empty());
  auto* advertisement = pending_advertisements[0];
  SimulateAdvertisementStarted(advertisement);
  base::RunLoop().RunUntilIdle();

  TestBluetoothAdvertisementObserver observer(advertisement);
  advertisement->Unregister(GetCallback(Call::EXPECTED),
                            GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
  SimulateAdvertisementStopped(advertisement);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(observer.released());
  EXPECT_EQ(1u, observer.released_count());
  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}

TEST_P(BluetoothTestWinrt, FailUnregisterAdvertisement) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
      BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
  advertisement_data->set_manufacturer_data(
      BluetoothAdvertisement::ManufacturerData());

  InitWithFakeAdapter();
  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      GetCreateAdvertisementCallback(Call::EXPECTED),
      GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
  auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
  ASSERT_FALSE(pending_advertisements.empty());
  auto* advertisement = pending_advertisements[0];
  SimulateAdvertisementStarted(advertisement);
  base::RunLoop().RunUntilIdle();

  TestBluetoothAdvertisementObserver observer(advertisement);
  advertisement->Unregister(GetCallback(Call::NOT_EXPECTED),
                            GetAdvertisementErrorCallback(Call::EXPECTED));
  SimulateAdvertisementError(advertisement,
                             BluetoothAdvertisement::ERROR_RESET_ADVERTISING);
  base::RunLoop().RunUntilIdle();

  // Expect no change to the observer status.
  EXPECT_FALSE(observer.released());
  EXPECT_EQ(0u, observer.released_count());
  EXPECT_EQ(BluetoothAdvertisement::ERROR_RESET_ADVERTISING,
            last_advertisement_error_code_);
  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}

TEST_P(BluetoothTestWinrt, RegisterAdvertisementWithInvalidData) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  // WinRT only accepts ManufacturerData in the payload, other data should be
  // rejected.
  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
      BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
  advertisement_data->set_service_data(BluetoothAdvertisement::ServiceData());

  InitWithFakeAdapter();
  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      GetCreateAdvertisementCallback(Call::NOT_EXPECTED),
      GetAdvertisementErrorCallback(Call::EXPECTED));
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(BluetoothAdvertisement::ERROR_STARTING_ADVERTISEMENT,
            last_advertisement_error_code_);
  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}

TEST_P(BluetoothTestWinrt, RegisterMultipleAdvertisements) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitWithFakeAdapter();
  constexpr size_t kNumAdvertisements = 10u;

  for (size_t i = 0; i < kNumAdvertisements; ++i) {
    auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
        BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
    advertisement_data->set_manufacturer_data(
        BluetoothAdvertisement::ManufacturerData());

    adapter_->RegisterAdvertisement(
        std::move(advertisement_data),
        GetCreateAdvertisementCallback(Call::EXPECTED),
        GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
  }

  base::RunLoop().RunUntilIdle();
  auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
  ASSERT_EQ(kNumAdvertisements, pending_advertisements.size());
  for (size_t i = 0; i < kNumAdvertisements; ++i)
    SimulateAdvertisementStarted(pending_advertisements[i]);

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}

TEST_P(BluetoothTestWinrt, UnregisterAdvertisementWhilePendingUnregister) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitWithFakeAdapter();
  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
      BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
  advertisement_data->set_manufacturer_data(
      BluetoothAdvertisement::ManufacturerData());

  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      GetCreateAdvertisementCallback(Call::EXPECTED),
      GetAdvertisementErrorCallback(Call::NOT_EXPECTED));

  base::RunLoop().RunUntilIdle();
  auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
  ASSERT_EQ(1u, pending_advertisements.size());
  auto* advertisement = pending_advertisements[0];
  SimulateAdvertisementStarted(advertisement);
  base::RunLoop().RunUntilIdle();

  TestBluetoothAdvertisementObserver observer(advertisement);
  advertisement->Unregister(GetCallback(Call::EXPECTED),
                            GetAdvertisementErrorCallback(Call::NOT_EXPECTED));

  // Schedule another Unregister, which is expected to fail.
  advertisement->Unregister(GetCallback(Call::NOT_EXPECTED),
                            GetAdvertisementErrorCallback(Call::EXPECTED));
  base::RunLoop().RunUntilIdle();
  // Expect no change to the observer status.
  EXPECT_FALSE(observer.released());
  EXPECT_EQ(0u, observer.released_count());
  EXPECT_EQ(BluetoothAdvertisement::ERROR_RESET_ADVERTISING,
            last_advertisement_error_code_);

  // Simulate success of the first unregistration.
  SimulateAdvertisementStopped(advertisement);
  base::RunLoop().RunUntilIdle();

  EXPECT_TRUE(observer.released());
  EXPECT_EQ(1u, observer.released_count());
  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}

TEST_P(BluetoothTestWinrt, DoubleUnregisterAdvertisement) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitWithFakeAdapter();
  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
      BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
  advertisement_data->set_manufacturer_data(
      BluetoothAdvertisement::ManufacturerData());

  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      GetCreateAdvertisementCallback(Call::EXPECTED),
      GetAdvertisementErrorCallback(Call::NOT_EXPECTED));

  base::RunLoop().RunUntilIdle();
  auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
  ASSERT_EQ(1u, pending_advertisements.size());
  auto* advertisement = pending_advertisements[0];
  SimulateAdvertisementStarted(advertisement);
  base::RunLoop().RunUntilIdle();

  // Perform two unregistrations after each other. Both should succeed.
  TestBluetoothAdvertisementObserver observer(advertisement);
  advertisement->Unregister(GetCallback(Call::EXPECTED),
                            GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
  SimulateAdvertisementStopped(advertisement);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(observer.released());
  EXPECT_EQ(1u, observer.released_count());

  advertisement->Unregister(GetCallback(Call::EXPECTED),
                            GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
  SimulateAdvertisementStopped(advertisement);
  base::RunLoop().RunUntilIdle();
  // The second unregister is a no-op, and should not notify observers again.
  EXPECT_TRUE(observer.released());
  EXPECT_EQ(1u, observer.released_count());

  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());
}

TEST_P(BluetoothTestWinrt, SimulateAdvertisementStoppedByOS) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }

  InitWithFakeAdapter();
  auto advertisement_data = std::make_unique<BluetoothAdvertisement::Data>(
      BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
  advertisement_data->set_manufacturer_data(
      BluetoothAdvertisement::ManufacturerData());

  adapter_->RegisterAdvertisement(
      std::move(advertisement_data),
      GetCreateAdvertisementCallback(Call::EXPECTED),
      GetAdvertisementErrorCallback(Call::NOT_EXPECTED));

  base::RunLoop().RunUntilIdle();
  auto pending_advertisements = adapter_->GetPendingAdvertisementsForTesting();
  ASSERT_EQ(1u, pending_advertisements.size());
  auto* advertisement = pending_advertisements[0];
  SimulateAdvertisementStarted(advertisement);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(adapter_->GetPendingAdvertisementsForTesting().empty());

  TestBluetoothAdvertisementObserver observer(advertisement);
  // Simulate the OS stopping the advertisement. This should notify the
  // |observer|.
  SimulateAdvertisementStopped(advertisement);
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(observer.released());
  EXPECT_EQ(1u, observer.released_count());

  // While Unregister() is a no-op now, we still expect an invocation of the
  // success callback, but no change to the |observer| state.
  advertisement->Unregister(GetCallback(Call::EXPECTED),
                            GetAdvertisementErrorCallback(Call::NOT_EXPECTED));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(observer.released());
  EXPECT_EQ(1u, observer.released_count());
}

#endif  // BUILDFLAG(IS_WIN)

#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && \
    !defined(USE_CAST_BLUETOOTH_ADAPTER)
#define MAYBE_RegisterLocalGattServices
#else
#define MAYBE_RegisterLocalGattServices
#endif
TEST_F(BluetoothTest, MAYBE_RegisterLocalGattServices) {}

#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && \
    !defined(USE_CAST_BLUETOOTH_ADAPTER)
#define MAYBE_RegisterMultipleServices
#else
#define MAYBE_RegisterMultipleServices
#endif
TEST_F(BluetoothTest, MAYBE_RegisterMultipleServices) {}

#if (BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)) && \
    !defined(USE_CAST_BLUETOOTH_ADAPTER)
#define MAYBE_DeleteServices
#else
#define MAYBE_DeleteServices
#endif
TEST_F(BluetoothTest, MAYBE_DeleteServices) {}

// This test should only be enabled for platforms that uses the
// BluetoothAdapter#RemoveOutdatedDevices function to purge outdated
// devices.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_EnsureUpdatedTimestamps
#else
#define MAYBE_EnsureUpdatedTimestamps
#endif
TEST_F(BluetoothTest, MAYBE_EnsureUpdatedTimestamps) {}

// This test should only be enabled for platforms that uses the
// BluetoothAdapter#RemoveOutdatedDevices function to purge outdated
// devices.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoveOutdatedDevices
#else
#define MAYBE_RemoveOutdatedDevices
#endif
TEST_F(BluetoothTest, MAYBE_RemoveOutdatedDevices) {}

// This test should only be enabled for platforms that uses the
// BluetoothAdapter#RemoveOutdatedDevices function to purge outdated
// devices.
#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_APPLE)
#define MAYBE_RemoveOutdatedDeviceGattConnect
#else
#define MAYBE_RemoveOutdatedDeviceGattConnect
#endif
TEST_F(BluetoothTest, MAYBE_RemoveOutdatedDeviceGattConnect) {}

#if BUILDFLAG(IS_APPLE)
// Simulate two devices being connected before calling
// RetrieveGattConnectedDevicesWithDiscoveryFilter() with no service filter.
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceWithNoFilter) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }
  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);

  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
  BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
  std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
      adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
          discovery_filter);

  EXPECT_EQ(2u, result.size());
  for (const auto& pair : result) {
    EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
    EXPECT_TRUE(pair.second.empty());
  }
  EXPECT_EQ(BluetoothDevice::UUIDSet({BluetoothUUID(kTestUUIDGenericAccess)}),
            RetrieveConnectedPeripheralServiceUUIDs());
  EXPECT_EQ(2, observer.device_added_count());
  EXPECT_EQ(2u, adapter_->GetDevices().size());
}
#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_APPLE)
// Simulate two devices being connected before calling
// RetrieveGattConnectedDevicesWithDiscoveryFilter() with one service filter.
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceWithFilter) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }
  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);

  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
  BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
  BluetoothUUID heart_service_uuid = BluetoothUUID(kTestUUIDHeartRate);
  AddDeviceFilterWithUUID(&discovery_filter, heart_service_uuid);
  std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
      adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
          discovery_filter);

  EXPECT_EQ(1u, result.size());
  for (const auto& pair : result) {
    EXPECT_EQ(kTestDeviceAddress2, pair.first->GetAddress());
    EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
    EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}), pair.second);
  }
  EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}),
            RetrieveConnectedPeripheralServiceUUIDs());
  EXPECT_EQ(1, observer.device_added_count());
  EXPECT_EQ(1u, adapter_->GetDevices().size());
}
#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_APPLE)
// Simulate two devices being connected before calling
// RetrieveGattConnectedDevicesWithDiscoveryFilter() with one service filter
// that doesn't match.
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceWithWrongFilter) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }
  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);

  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
  BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
  AddDeviceFilterWithUUID(&discovery_filter, BluetoothUUID(kTestUUIDLinkLoss));
  std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
      adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
          discovery_filter);

  EXPECT_TRUE(result.empty());
  EXPECT_EQ(
      BluetoothDevice::UUIDSet({device::BluetoothUUID(kTestUUIDLinkLoss)}),
      RetrieveConnectedPeripheralServiceUUIDs());
  EXPECT_EQ(0, observer.device_added_count());
  EXPECT_EQ(0u, adapter_->GetDevices().size());
}
#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_APPLE)
// Simulate two devices being connected before calling
// RetrieveGattConnectedDevicesWithDiscoveryFilter() with two service filters
// that both match.
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceWithTwoFilters) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }
  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);

  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
  BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
  BluetoothUUID heart_service_uuid = BluetoothUUID(kTestUUIDHeartRate);
  AddDeviceFilterWithUUID(&discovery_filter, heart_service_uuid);
  BluetoothUUID generic_service_uuid = BluetoothUUID(kTestUUIDGenericAccess);
  AddDeviceFilterWithUUID(&discovery_filter, generic_service_uuid);
  std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
      adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
          discovery_filter);

  EXPECT_EQ(2u, result.size());
  for (const auto& pair : result) {
    EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
    if (pair.first->GetAddress() == kTestDeviceAddress2) {
      EXPECT_EQ(
          BluetoothDevice::UUIDSet({heart_service_uuid, generic_service_uuid}),
          pair.second);
    } else if (pair.first->GetAddress() == kTestDeviceAddress1) {
      EXPECT_EQ(BluetoothDevice::UUIDSet({generic_service_uuid}), pair.second);
    } else {
      // Unknown device.
      EXPECT_TRUE(false);
    }
  }
  EXPECT_EQ(
      BluetoothDevice::UUIDSet({generic_service_uuid, heart_service_uuid}),
      RetrieveConnectedPeripheralServiceUUIDs());
  EXPECT_EQ(2, observer.device_added_count());
  EXPECT_EQ(2u, adapter_->GetDevices().size());
}
#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_APPLE)
// Simulate two devices being connected before calling
// RetrieveGattConnectedDevicesWithDiscoveryFilter() with one service filter
// that one match device, and then
// RetrieveGattConnectedDevicesWithDiscoveryFilter() again.
TEST_F(BluetoothTest, DiscoverConnectedLowEnergyDeviceTwice) {
  if (!PlatformSupportsLowEnergy()) {
    GTEST_SKIP() << "Low Energy Bluetooth unavailable, skipping unit test.";
  }
  InitWithFakeAdapter();
  TestBluetoothAdapterObserver observer(adapter_);

  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::GENERIC_DEVICE);
  SimulateConnectedLowEnergyDevice(ConnectedDeviceType::HEART_RATE_DEVICE);
  BluetoothDiscoveryFilter discovery_filter(BLUETOOTH_TRANSPORT_LE);
  BluetoothUUID heart_service_uuid = BluetoothUUID(kTestUUIDHeartRate);
  AddDeviceFilterWithUUID(&discovery_filter, heart_service_uuid);
  std::unordered_map<BluetoothDevice*, BluetoothDevice::UUIDSet> result =
      adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
          discovery_filter);

  EXPECT_EQ(1u, result.size());
  for (const auto& pair : result) {
    EXPECT_EQ(kTestDeviceAddress2, pair.first->GetAddress());
    EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
    EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}), pair.second);
  }
  EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}),
            RetrieveConnectedPeripheralServiceUUIDs());
  EXPECT_EQ(1, observer.device_added_count());
  EXPECT_EQ(1u, adapter_->GetDevices().size());

  observer.Reset();
  ResetRetrieveConnectedPeripheralServiceUUIDs();
  result = adapter_->RetrieveGattConnectedDevicesWithDiscoveryFilter(
      discovery_filter);

  EXPECT_EQ(1u, result.size());
  for (const auto& pair : result) {
    EXPECT_EQ(kTestDeviceAddress2, pair.first->GetAddress());
    EXPECT_TRUE(adapter_->GetDevice(pair.first->GetAddress()));
    EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}), pair.second);
  }
  EXPECT_EQ(BluetoothDevice::UUIDSet({heart_service_uuid}),
            RetrieveConnectedPeripheralServiceUUIDs());

  EXPECT_EQ(0, observer.device_added_count());
  EXPECT_EQ(1u, adapter_->GetDevices().size());
}
#endif  // BUILDFLAG(IS_APPLE)

#if BUILDFLAG(IS_WIN)
INSTANTIATE_TEST_SUITE_P(All,
                         BluetoothTestWinrt,
                         ::testing::ValuesIn(kBluetoothTestWinrtParam));
#endif  // BUILDFLAG(IS_WIN)

}  // namespace device