chromium/device/bluetooth/test/fake_bluetooth_adapter_winrt.cc

// Copyright 2018 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/test/fake_bluetooth_adapter_winrt.h"

#include <utility>

#include "base/functional/bind.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/task/sequenced_task_runner.h"
#include "base/win/async_operation.h"
#include "device/bluetooth/test/bluetooth_test.h"

namespace device {

namespace {

// In order to avoid a name clash with device::BluetoothAdapter we need this
// auxiliary namespace.
namespace uwp {
using ABI::Windows::Devices::Bluetooth::BluetoothAdapter;
}  // namespace uwp
using ABI::Windows::Devices::Bluetooth::IBluetoothAdapter;
using ABI::Windows::Devices::Radios::Radio;
using ABI::Windows::Foundation::IAsyncOperation;
using Microsoft::WRL::ComPtr;
using Microsoft::WRL::Make;

}  // namespace

FakeBluetoothAdapterWinrt::FakeBluetoothAdapterWinrt(
    std::string_view address,
    Microsoft::WRL::ComPtr<ABI::Windows::Devices::Radios::IRadio> radio)
    : raw_address_(ToRawBluetoothAddress(address)), radio_(std::move(radio)) {}

FakeBluetoothAdapterWinrt::~FakeBluetoothAdapterWinrt() = default;

// static
uint64_t FakeBluetoothAdapterWinrt::ToRawBluetoothAddress(
    std::string_view address) {
  uint64_t raw_address;
  const bool result = base::HexStringToUInt64(
      base::StrCat(base::SplitStringPiece(address, ":", base::TRIM_WHITESPACE,
                                          base::SPLIT_WANT_ALL)),
      &raw_address);
  DCHECK(result);
  return raw_address;
}

HRESULT FakeBluetoothAdapterWinrt::get_DeviceId(HSTRING* value) {
  // The actual device id does not matter for testing, as long as this method
  // returns a success code.
  return S_OK;
}

HRESULT FakeBluetoothAdapterWinrt::get_BluetoothAddress(UINT64* value) {
  *value = raw_address_;
  return S_OK;
}

HRESULT FakeBluetoothAdapterWinrt::get_IsClassicSupported(boolean* value) {
  return E_NOTIMPL;
}

HRESULT FakeBluetoothAdapterWinrt::get_IsLowEnergySupported(boolean* value) {
  return E_NOTIMPL;
}

HRESULT FakeBluetoothAdapterWinrt::get_IsPeripheralRoleSupported(
    boolean* value) {
  *value = true;
  return S_OK;
}

HRESULT FakeBluetoothAdapterWinrt::get_IsCentralRoleSupported(boolean* value) {
  return E_NOTIMPL;
}

HRESULT FakeBluetoothAdapterWinrt::get_IsAdvertisementOffloadSupported(
    boolean* value) {
  return E_NOTIMPL;
}

HRESULT FakeBluetoothAdapterWinrt::GetRadioAsync(
    IAsyncOperation<Radio*>** operation) {
  auto async_op = Make<base::win::AsyncOperation<Radio*>>();
  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE, base::BindOnce(async_op->callback(), radio_));
  *operation = async_op.Detach();
  return S_OK;
}

FakeBluetoothAdapterStaticsWinrt::FakeBluetoothAdapterStaticsWinrt(
    ComPtr<IBluetoothAdapter> default_adapter)
    : default_adapter_(std::move(default_adapter)) {}

FakeBluetoothAdapterStaticsWinrt::~FakeBluetoothAdapterStaticsWinrt() = default;

HRESULT FakeBluetoothAdapterStaticsWinrt::GetDeviceSelector(HSTRING* result) {
  return E_NOTIMPL;
}

HRESULT FakeBluetoothAdapterStaticsWinrt::FromIdAsync(
    HSTRING device_id,
    IAsyncOperation<uwp::BluetoothAdapter*>** operation) {
  return E_NOTIMPL;
}

HRESULT FakeBluetoothAdapterStaticsWinrt::GetDefaultAsync(
    IAsyncOperation<uwp::BluetoothAdapter*>** operation) {
  // Here we mimick production code and do not return an error code if no
  // default adapter is present. Just as production code, the async operation
  // completes successfully and returns a nullptr as adapter in this case.
  auto async_op = Make<base::win::AsyncOperation<uwp::BluetoothAdapter*>>();
  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE, base::BindOnce(async_op->callback(), default_adapter_));
  *operation = async_op.Detach();
  return S_OK;
}

}  // namespace device