Commit ce8d3b30 authored by Jan Wilken Doerrie's avatar Jan Wilken Doerrie Committed by Commit Bot

[bluetooth] Implement GATT Connections for WinRT

This change implements initiating GATT connections for WinRT. While
currently no GATT discovery is attempted, this will be provided in a
future CL. GATT connections are created by obtaining an instance of
BluetoothLEDevice.

Bug: 821766
Change-Id: I7f20127a84b781859300af18b31da0e9ee24a32b
Reviewed-on: https://chromium-review.googlesource.com/1090217
Commit-Queue: Jan Wilken Dörrie <jdoerrie@chromium.org>
Reviewed-by: default avatarGiovanni Ortuño Urquidi <ortuno@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#571156}
parent 3c41dd4c
...@@ -390,7 +390,7 @@ void BluetoothAdapterWinrt::AddDiscoverySession( ...@@ -390,7 +390,7 @@ void BluetoothAdapterWinrt::AddDiscoverySession(
ble_advertisement_watcher_.Get(), ble_advertisement_watcher_.Get(),
&IBluetoothLEAdvertisementWatcher::add_Received, &IBluetoothLEAdvertisementWatcher::add_Received,
base::BindRepeating(&BluetoothAdapterWinrt::OnAdvertisementReceived, base::BindRepeating(&BluetoothAdapterWinrt::OnAdvertisementReceived,
base::Unretained(this))); weak_ptr_factory_.GetWeakPtr()));
if (!advertisement_received_token) { if (!advertisement_received_token) {
ui_task_runner_->PostTask( ui_task_runner_->PostTask(
FROM_HERE, FROM_HERE,
...@@ -528,6 +528,13 @@ BluetoothAdapterWinrt::ActivateBluetoothAdvertisementLEWatcherInstance( ...@@ -528,6 +528,13 @@ BluetoothAdapterWinrt::ActivateBluetoothAdvertisementLEWatcherInstance(
return watcher.CopyTo(instance); return watcher.CopyTo(instance);
} }
std::unique_ptr<BluetoothDeviceWinrt> BluetoothAdapterWinrt::CreateDevice(
uint64_t raw_address,
base::Optional<std::string> local_name) {
return std::make_unique<BluetoothDeviceWinrt>(this, raw_address,
std::move(local_name));
}
void BluetoothAdapterWinrt::OnGetDefaultAdapter( void BluetoothAdapterWinrt::OnGetDefaultAdapter(
base::ScopedClosureRunner on_init, base::ScopedClosureRunner on_init,
ComPtr<IBluetoothAdapter> adapter) { ComPtr<IBluetoothAdapter> adapter) {
...@@ -703,8 +710,7 @@ void BluetoothAdapterWinrt::OnAdvertisementReceived( ...@@ -703,8 +710,7 @@ void BluetoothAdapterWinrt::OnAdvertisementReceived(
bool was_inserted = false; bool was_inserted = false;
std::tie(it, was_inserted) = devices_.emplace( std::tie(it, was_inserted) = devices_.emplace(
std::move(bluetooth_address), std::move(bluetooth_address),
std::make_unique<BluetoothDeviceWinrt>(this, raw_bluetooth_address, CreateDevice(raw_bluetooth_address, GetDeviceName(received)));
GetDeviceName(received)));
DCHECK(was_inserted); DCHECK(was_inserted);
} }
......
...@@ -25,6 +25,8 @@ class ScopedClosureRunner; ...@@ -25,6 +25,8 @@ class ScopedClosureRunner;
namespace device { namespace device {
class BluetoothDeviceWinrt;
class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterWinrt : public BluetoothAdapter { class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterWinrt : public BluetoothAdapter {
public: public:
// BluetoothAdapter: // BluetoothAdapter:
...@@ -61,7 +63,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterWinrt : public BluetoothAdapter { ...@@ -61,7 +63,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterWinrt : public BluetoothAdapter {
protected: protected:
friend class BluetoothAdapterWin; friend class BluetoothAdapterWin;
friend class BluetoothTestWin; friend class BluetoothTestWinrt;
BluetoothAdapterWinrt(); BluetoothAdapterWinrt();
~BluetoothAdapterWinrt() override; ~BluetoothAdapterWinrt() override;
...@@ -100,6 +102,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterWinrt : public BluetoothAdapter { ...@@ -100,6 +102,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterWinrt : public BluetoothAdapter {
virtual HRESULT ActivateBluetoothAdvertisementLEWatcherInstance( virtual HRESULT ActivateBluetoothAdvertisementLEWatcherInstance(
ABI::Windows::Devices::Bluetooth::Advertisement:: ABI::Windows::Devices::Bluetooth::Advertisement::
IBluetoothLEAdvertisementWatcher** instance) const; IBluetoothLEAdvertisementWatcher** instance) const;
virtual std::unique_ptr<BluetoothDeviceWinrt> CreateDevice(
uint64_t raw_address,
base::Optional<std::string> local_name);
private: private:
void OnGetDefaultAdapter( void OnGetDefaultAdapter(
......
...@@ -593,6 +593,17 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDevice { ...@@ -593,6 +593,17 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDevice {
FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDevices); FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDevices);
FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDeviceGattConnect); FRIEND_TEST_ALL_PREFIXES(BluetoothTest, RemoveOutdatedDeviceGattConnect);
FRIEND_TEST_ALL_PREFIXES(
BluetoothTestWinrtOnly,
BluetoothGattConnection_DisconnectGatt_SimulateConnect);
FRIEND_TEST_ALL_PREFIXES(
BluetoothTestWinrtOnly,
BluetoothGattConnection_DisconnectGatt_SimulateDisconnect);
FRIEND_TEST_ALL_PREFIXES(BluetoothTestWinrtOnly,
BluetoothGattConnection_ErrorAfterConnection);
FRIEND_TEST_ALL_PREFIXES(BluetoothTestWinrtOnly,
BluetoothGattConnection_DisconnectGatt_Cleanup);
// Helper class to easily update the sets of UUIDs and keep them in sync with // Helper class to easily update the sets of UUIDs and keep them in sync with
// the set of all the device's UUIDs. // the set of all the device's UUIDs.
class DeviceUUIDs { class DeviceUUIDs {
......
...@@ -905,7 +905,11 @@ TEST_F(BluetoothTest, MAYBE_GetName_NullName) { ...@@ -905,7 +905,11 @@ TEST_F(BluetoothTest, MAYBE_GetName_NullName) {
#define MAYBE_CreateGattConnection DISABLED_CreateGattConnection #define MAYBE_CreateGattConnection DISABLED_CreateGattConnection
#endif #endif
// Basic CreateGattConnection test. // Basic CreateGattConnection test.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly, CreateGattConnection) {
#else
TEST_F(BluetoothTest, MAYBE_CreateGattConnection) { TEST_F(BluetoothTest, MAYBE_CreateGattConnection) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -932,7 +936,11 @@ TEST_F(BluetoothTest, MAYBE_CreateGattConnection) { ...@@ -932,7 +936,11 @@ TEST_F(BluetoothTest, MAYBE_CreateGattConnection) {
#define MAYBE_DisconnectionNotifiesDeviceChanged \ #define MAYBE_DisconnectionNotifiesDeviceChanged \
DISABLED_DisconnectionNotifiesDeviceChanged DISABLED_DisconnectionNotifiesDeviceChanged
#endif #endif
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly, DisconnectionNotifiesDeviceChanged) {
#else
TEST_F(BluetoothTest, MAYBE_DisconnectionNotifiesDeviceChanged) { TEST_F(BluetoothTest, MAYBE_DisconnectionNotifiesDeviceChanged) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -964,7 +972,11 @@ TEST_F(BluetoothTest, MAYBE_DisconnectionNotifiesDeviceChanged) { ...@@ -964,7 +972,11 @@ TEST_F(BluetoothTest, MAYBE_DisconnectionNotifiesDeviceChanged) {
#endif #endif
// Creates BluetoothGattConnection instances and tests that the interface // Creates BluetoothGattConnection instances and tests that the interface
// functions even when some Disconnect and the BluetoothDevice is destroyed. // functions even when some Disconnect and the BluetoothDevice is destroyed.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly, BluetoothGattConnection) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection) { TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -978,6 +990,7 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection) { ...@@ -978,6 +990,7 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection) {
ResetEventCounts(); ResetEventCounts();
device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED), device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
GetConnectErrorCallback(Call::NOT_EXPECTED)); GetConnectErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, gatt_connection_attempts_); EXPECT_EQ(1, gatt_connection_attempts_);
SimulateGattConnection(device); SimulateGattConnection(device);
...@@ -1085,7 +1098,11 @@ TEST_F(BluetoothTest, ...@@ -1085,7 +1098,11 @@ TEST_F(BluetoothTest,
DISABLED_BluetoothGattConnection_AlreadyConnected DISABLED_BluetoothGattConnection_AlreadyConnected
#endif #endif
// Calls CreateGattConnection after already connected. // Calls CreateGattConnection after already connected.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly, BluetoothGattConnection_AlreadyConnected) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_AlreadyConnected) { TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_AlreadyConnected) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -1117,8 +1134,13 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_AlreadyConnected) { ...@@ -1117,8 +1134,13 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_AlreadyConnected) {
DISABLED_BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected DISABLED_BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected
#endif #endif
// Creates BluetoothGattConnection after one exists that has disconnected. // Creates BluetoothGattConnection after one exists that has disconnected.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly,
BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected) {
#else
TEST_F(BluetoothTest, TEST_F(BluetoothTest,
MAYBE_BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected) { MAYBE_BluetoothGattConnection_NewConnectionLeavesPreviousDisconnected) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -1158,8 +1180,13 @@ TEST_F(BluetoothTest, ...@@ -1158,8 +1180,13 @@ TEST_F(BluetoothTest,
DISABLED_BluetoothGattConnection_DisconnectWhenObjectsDestroyed DISABLED_BluetoothGattConnection_DisconnectWhenObjectsDestroyed
#endif #endif
// Deletes BluetoothGattConnection causing disconnection. // Deletes BluetoothGattConnection causing disconnection.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly,
BluetoothGattConnection_DisconnectWhenObjectsDestroyed) {
#else
TEST_F(BluetoothTest, TEST_F(BluetoothTest,
MAYBE_BluetoothGattConnection_DisconnectWhenObjectsDestroyed) { MAYBE_BluetoothGattConnection_DisconnectWhenObjectsDestroyed) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -1190,7 +1217,11 @@ TEST_F(BluetoothTest, ...@@ -1190,7 +1217,11 @@ TEST_F(BluetoothTest,
DISABLED_BluetoothGattConnection_DisconnectInProgress DISABLED_BluetoothGattConnection_DisconnectInProgress
#endif #endif
// Starts process of disconnecting and then calls BluetoothGattConnection. // Starts process of disconnecting and then calls BluetoothGattConnection.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly, BluetoothGattConnection_DisconnectInProgress) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_DisconnectInProgress) { TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_DisconnectInProgress) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -1239,7 +1270,11 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_DisconnectInProgress) { ...@@ -1239,7 +1270,11 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_DisconnectInProgress) {
#endif #endif
// Calls CreateGattConnection but receives notice that the device disconnected // Calls CreateGattConnection but receives notice that the device disconnected
// before it ever connects. // before it ever connects.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly, BluetoothGattConnection_SimulateDisconnect) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_SimulateDisconnect) { TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_SimulateDisconnect) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -1251,6 +1286,7 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_SimulateDisconnect) { ...@@ -1251,6 +1286,7 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_SimulateDisconnect) {
ResetEventCounts(); ResetEventCounts();
device->CreateGattConnection(GetGattConnectionCallback(Call::NOT_EXPECTED), device->CreateGattConnection(GetGattConnectionCallback(Call::NOT_EXPECTED),
GetConnectErrorCallback(Call::EXPECTED)); GetConnectErrorCallback(Call::EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, gatt_connection_attempts_); EXPECT_EQ(1, gatt_connection_attempts_);
SimulateGattDisconnection(device); SimulateGattDisconnection(device);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -1267,8 +1303,13 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_SimulateDisconnect) { ...@@ -1267,8 +1303,13 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_SimulateDisconnect) {
DISABLED_BluetoothGattConnection_DisconnectGatt_SimulateConnect DISABLED_BluetoothGattConnection_DisconnectGatt_SimulateConnect
#endif #endif
// Calls CreateGattConnection & DisconnectGatt, then simulates connection. // Calls CreateGattConnection & DisconnectGatt, then simulates connection.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly,
BluetoothGattConnection_DisconnectGatt_SimulateConnect) {
#else
TEST_F(BluetoothTest, TEST_F(BluetoothTest,
MAYBE_BluetoothGattConnection_DisconnectGatt_SimulateConnect) { MAYBE_BluetoothGattConnection_DisconnectGatt_SimulateConnect) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -1280,9 +1321,14 @@ TEST_F(BluetoothTest, ...@@ -1280,9 +1321,14 @@ TEST_F(BluetoothTest,
ResetEventCounts(); ResetEventCounts();
device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED), device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
GetConnectErrorCallback(Call::NOT_EXPECTED)); GetConnectErrorCallback(Call::NOT_EXPECTED));
device->DisconnectGatt(); base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, gatt_connection_attempts_); EXPECT_EQ(1, gatt_connection_attempts_);
#if !defined(OS_WIN)
// On Windows there is currently no way to cancel a pending GATT connection
// from the callers site.
device->DisconnectGatt();
EXPECT_EQ(1, gatt_disconnection_attempts_); EXPECT_EQ(1, gatt_disconnection_attempts_);
#endif
SimulateGattConnection(device); SimulateGattConnection(device);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
...@@ -1398,7 +1444,11 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_DisconnectGatt_Cleanup) { ...@@ -1398,7 +1444,11 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_DisconnectGatt_Cleanup) {
#endif #endif
// Calls CreateGattConnection, but simulate errors connecting. Also, verifies // Calls CreateGattConnection, but simulate errors connecting. Also, verifies
// multiple errors should only invoke callbacks once. // multiple errors should only invoke callbacks once.
#if defined(OS_WIN)
TEST_P(BluetoothTestWinrtOnly, BluetoothGattConnection_ErrorAfterConnection) {
#else
TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_ErrorAfterConnection) { TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_ErrorAfterConnection) {
#endif
if (!PlatformSupportsLowEnergy()) { if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return; return;
...@@ -1410,15 +1460,17 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_ErrorAfterConnection) { ...@@ -1410,15 +1460,17 @@ TEST_F(BluetoothTest, MAYBE_BluetoothGattConnection_ErrorAfterConnection) {
ResetEventCounts(); ResetEventCounts();
device->CreateGattConnection(GetGattConnectionCallback(Call::NOT_EXPECTED), device->CreateGattConnection(GetGattConnectionCallback(Call::NOT_EXPECTED),
GetConnectErrorCallback(Call::EXPECTED)); GetConnectErrorCallback(Call::EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, gatt_connection_attempts_); EXPECT_EQ(1, gatt_connection_attempts_);
SimulateGattConnectionError(device, BluetoothDevice::ERROR_AUTH_FAILED); SimulateGattConnectionError(device, BluetoothDevice::ERROR_AUTH_FAILED);
SimulateGattConnectionError(device, BluetoothDevice::ERROR_FAILED); SimulateGattConnectionError(device, BluetoothDevice::ERROR_FAILED);
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
#if defined(OS_ANDROID) #if defined(OS_ANDROID) || defined(OS_WIN)
// TODO: Change to ERROR_AUTH_FAILED. We should be getting a callback // TODO: Change to ERROR_AUTH_FAILED. We should be getting a callback
// only with the first error, but our android framework doesn't yet // only with the first error, but our android framework doesn't yet
// support sending different errors. // support sending different errors.
// http://crbug.com/578191 // http://crbug.com/578191
// On Windows, any GattConnectioError will result in ERROR_FAILED.
EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_); EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_);
#else #else
EXPECT_EQ(BluetoothDevice::ERROR_AUTH_FAILED, last_connect_error_code_); EXPECT_EQ(BluetoothDevice::ERROR_AUTH_FAILED, last_connect_error_code_);
......
...@@ -4,22 +4,89 @@ ...@@ -4,22 +4,89 @@
#include "device/bluetooth/bluetooth_device_winrt.h" #include "device/bluetooth/bluetooth_device_winrt.h"
#include <windows.foundation.h>
#include <wrl/event.h>
#include <utility> #include <utility>
#include "base/bind_helpers.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/win/core_winrt_util.h"
#include "base/win/scoped_hstring.h"
#include "device/bluetooth/bluetooth_adapter_winrt.h" #include "device/bluetooth/bluetooth_adapter_winrt.h"
#include "device/bluetooth/event_utils_winrt.h"
namespace device { namespace device {
BluetoothDeviceWinrt::BluetoothDeviceWinrt(BluetoothAdapterWinrt* adapter, namespace {
uint64_t raw_address,
base::Optional<std::string> name) using ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus;
using ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus_Connected;
using ABI::Windows::Devices::Bluetooth::BluetoothLEDevice;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus_Success;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceServicesResult;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceServicesResult;
using ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice;
using ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice3;
using ABI::Windows::Devices::Bluetooth::IBluetoothLEDeviceStatics;
using ABI::Windows::Foundation::IAsyncOperation;
using ABI::Windows::Foundation::IClosable;
using Microsoft::WRL::ComPtr;
void CloseDevice(ComPtr<IBluetoothLEDevice> ble_device) {
if (!ble_device)
return;
ComPtr<IClosable> closable;
HRESULT hr = ble_device.As(&closable);
if (FAILED(hr)) {
VLOG(2) << "As IClosable failed: " << logging::SystemErrorCodeToString(hr);
return;
}
hr = closable->Close();
if (FAILED(hr)) {
VLOG(2) << "IClosable::close() failed: "
<< logging::SystemErrorCodeToString(hr);
}
}
void RemoveConnectionStatusHandler(IBluetoothLEDevice* ble_device,
EventRegistrationToken token) {
HRESULT hr = ble_device->remove_ConnectionStatusChanged(token);
if (FAILED(hr)) {
VLOG(2) << "Removing ConnectionStatus Handler failed: "
<< logging::SystemErrorCodeToString(hr);
}
}
} // namespace
BluetoothDeviceWinrt::BluetoothDeviceWinrt(
BluetoothAdapterWinrt* adapter,
uint64_t raw_address,
base::Optional<std::string> local_name)
: BluetoothDevice(adapter), : BluetoothDevice(adapter),
raw_address_(raw_address),
address_(CanonicalizeAddress(raw_address)), address_(CanonicalizeAddress(raw_address)),
name_(std::move(name)) {} local_name_(std::move(local_name)),
weak_ptr_factory_(this) {}
BluetoothDeviceWinrt::~BluetoothDeviceWinrt() = default; BluetoothDeviceWinrt::~BluetoothDeviceWinrt() {
CloseDevice(ble_device_);
if (!connection_changed_token_)
return;
RemoveConnectionStatusHandler(ble_device_.Get(), *connection_changed_token_);
}
uint32_t BluetoothDeviceWinrt::GetBluetoothClass() const { uint32_t BluetoothDeviceWinrt::GetBluetoothClass() const {
NOTIMPLEMENTED(); NOTIMPLEMENTED();
...@@ -57,7 +124,17 @@ uint16_t BluetoothDeviceWinrt::GetAppearance() const { ...@@ -57,7 +124,17 @@ uint16_t BluetoothDeviceWinrt::GetAppearance() const {
} }
base::Optional<std::string> BluetoothDeviceWinrt::GetName() const { base::Optional<std::string> BluetoothDeviceWinrt::GetName() const {
return name_; if (!ble_device_)
return local_name_;
HSTRING name;
HRESULT hr = ble_device_->get_Name(&name);
if (FAILED(hr)) {
VLOG(2) << "Getting Name failed: " << logging::SystemErrorCodeToString(hr);
return local_name_;
}
return base::win::ScopedHString(name).GetAsUTF8();
} }
bool BluetoothDeviceWinrt::IsPaired() const { bool BluetoothDeviceWinrt::IsPaired() const {
...@@ -66,13 +143,22 @@ bool BluetoothDeviceWinrt::IsPaired() const { ...@@ -66,13 +143,22 @@ bool BluetoothDeviceWinrt::IsPaired() const {
} }
bool BluetoothDeviceWinrt::IsConnected() const { bool BluetoothDeviceWinrt::IsConnected() const {
NOTIMPLEMENTED(); return IsGattConnected();
return false;
} }
bool BluetoothDeviceWinrt::IsGattConnected() const { bool BluetoothDeviceWinrt::IsGattConnected() const {
NOTIMPLEMENTED(); if (!ble_device_)
return false; return false;
BluetoothConnectionStatus status;
HRESULT hr = ble_device_->get_ConnectionStatus(&status);
if (FAILED(hr)) {
VLOG(2) << "Getting ConnectionStatus failed: "
<< logging::SystemErrorCodeToString(hr);
return false;
}
return status == BluetoothConnectionStatus_Connected;
} }
bool BluetoothDeviceWinrt::IsConnectable() const { bool BluetoothDeviceWinrt::IsConnectable() const {
...@@ -171,11 +257,139 @@ std::string BluetoothDeviceWinrt::CanonicalizeAddress(uint64_t address) { ...@@ -171,11 +257,139 @@ std::string BluetoothDeviceWinrt::CanonicalizeAddress(uint64_t address) {
} }
void BluetoothDeviceWinrt::CreateGattConnectionImpl() { void BluetoothDeviceWinrt::CreateGattConnectionImpl() {
NOTIMPLEMENTED(); ComPtr<IBluetoothLEDeviceStatics> device_statics;
HRESULT hr = GetBluetoothLEDeviceStaticsActivationFactory(&device_statics);
if (FAILED(hr)) {
VLOG(2) << "GetBluetoothLEDeviceStaticsActivationFactory failed: "
<< logging::SystemErrorCodeToString(hr);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&BluetoothDeviceWinrt::DidFailToConnectGatt,
weak_ptr_factory_.GetWeakPtr(),
ConnectErrorCode::ERROR_FAILED));
return;
}
// Note: Even though we might have obtained a BluetoothLEDevice instance in
// the past, we need to request a new instance as the old device might have
// been closed. See also
// https://docs.microsoft.com/en-us/windows/uwp/devices-sensors/gatt-client#connecting-to-the-device
ComPtr<IAsyncOperation<BluetoothLEDevice*>> from_bluetooth_address_op;
hr = device_statics->FromBluetoothAddressAsync(raw_address_,
&from_bluetooth_address_op);
if (FAILED(hr)) {
VLOG(2) << "BluetoothLEDevice::FromBluetoothAddressAsync failed: "
<< logging::SystemErrorCodeToString(hr);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&BluetoothDeviceWinrt::DidFailToConnectGatt,
weak_ptr_factory_.GetWeakPtr(),
ConnectErrorCode::ERROR_FAILED));
return;
}
hr = PostAsyncResults(
std::move(from_bluetooth_address_op),
base::BindOnce(&BluetoothDeviceWinrt::OnFromBluetoothAddress,
weak_ptr_factory_.GetWeakPtr()));
if (FAILED(hr)) {
VLOG(2) << "PostAsyncResults failed: "
<< logging::SystemErrorCodeToString(hr);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&BluetoothDeviceWinrt::DidFailToConnectGatt,
weak_ptr_factory_.GetWeakPtr(),
ConnectErrorCode::ERROR_FAILED));
}
} }
void BluetoothDeviceWinrt::DisconnectGatt() { void BluetoothDeviceWinrt::DisconnectGatt() {
NOTIMPLEMENTED(); CloseDevice(ble_device_);
}
HRESULT BluetoothDeviceWinrt::GetBluetoothLEDeviceStaticsActivationFactory(
IBluetoothLEDeviceStatics** statics) const {
return base::win::GetActivationFactory<
IBluetoothLEDeviceStatics,
RuntimeClass_Windows_Devices_Bluetooth_BluetoothLEDevice>(statics);
}
void BluetoothDeviceWinrt::OnFromBluetoothAddress(
ComPtr<IBluetoothLEDevice> ble_device) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!ble_device) {
VLOG(2) << "Getting Device From Bluetooth Address failed.";
DidFailToConnectGatt(ConnectErrorCode::ERROR_FAILED);
return;
}
if (connection_changed_token_) {
// As we are about to replace |ble_device_| with |ble_device| we will also
// unregister the existing event handler and add a new one to the new
// device.
RemoveConnectionStatusHandler(ble_device_.Get(),
*connection_changed_token_);
}
ble_device_ = std::move(ble_device);
connection_changed_token_ = AddTypedEventHandler(
ble_device_.Get(), &IBluetoothLEDevice::add_ConnectionStatusChanged,
base::BindRepeating(&BluetoothDeviceWinrt::OnConnectionStatusChanged,
weak_ptr_factory_.GetWeakPtr()));
ComPtr<IBluetoothLEDevice3> ble_device_3;
HRESULT hr = ble_device_.As(&ble_device_3);
if (FAILED(hr)) {
VLOG(2) << "Obtaining IBluetoothLEDevice3 failed: "
<< logging::SystemErrorCodeToString(hr);
DidFailToConnectGatt(ConnectErrorCode::ERROR_FAILED);
return;
}
ComPtr<IAsyncOperation<GattDeviceServicesResult*>> get_gatt_services_op;
hr = ble_device_3->GetGattServicesAsync(&get_gatt_services_op);
if (FAILED(hr)) {
VLOG(2) << "BluetoothLEDevice::GetGattServicesAsync failed: "
<< logging::SystemErrorCodeToString(hr);
DidFailToConnectGatt(ConnectErrorCode::ERROR_FAILED);
return;
}
hr = PostAsyncResults(std::move(get_gatt_services_op),
base::BindOnce(&BluetoothDeviceWinrt::OnGetGattServices,
weak_ptr_factory_.GetWeakPtr()));
if (FAILED(hr)) {
VLOG(2) << "PostAsyncResults failed: "
<< logging::SystemErrorCodeToString(hr);
DidFailToConnectGatt(ConnectErrorCode::ERROR_FAILED);
}
}
void BluetoothDeviceWinrt::OnConnectionStatusChanged(
IBluetoothLEDevice* ble_device,
IInspectable* object) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
IsGattConnected() ? DidConnectGatt() : DidDisconnectGatt();
}
void BluetoothDeviceWinrt::OnGetGattServices(
ComPtr<IGattDeviceServicesResult> result) {
DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
if (!result)
DidFailToConnectGatt(ConnectErrorCode::ERROR_FAILED);
GattCommunicationStatus status;
HRESULT hr = result->get_Status(&status);
if (FAILED(hr)) {
VLOG(2) << "GattDeviceServicesResult::get_Status() failed: "
<< logging::SystemErrorCodeToString(hr);
return;
}
if (status != GattCommunicationStatus_Success)
DidFailToConnectGatt(ConnectErrorCode::ERROR_FAILED);
// In case of success a gatt connection is established and an invocation
// of OnConnectionStatusChanged() is expected.
} }
} // namespace device } // namespace device
...@@ -5,13 +5,18 @@ ...@@ -5,13 +5,18 @@
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_WINRT_H_ #ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_WINRT_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_WINRT_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_WINRT_H_
#include <windows.devices.bluetooth.h>
#include <wrl/client.h>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h" #include "base/optional.h"
#include "base/threading/thread_checker.h"
#include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_export.h" #include "device/bluetooth/bluetooth_export.h"
...@@ -23,7 +28,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice { ...@@ -23,7 +28,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice {
public: public:
BluetoothDeviceWinrt(BluetoothAdapterWinrt* adapter, BluetoothDeviceWinrt(BluetoothAdapterWinrt* adapter,
uint64_t raw_address, uint64_t raw_address,
base::Optional<std::string> name); base::Optional<std::string> local_name);
~BluetoothDeviceWinrt() override; ~BluetoothDeviceWinrt() override;
// BluetoothDevice: // BluetoothDevice:
...@@ -77,9 +82,39 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice { ...@@ -77,9 +82,39 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice {
void CreateGattConnectionImpl() override; void CreateGattConnectionImpl() override;
void DisconnectGatt() override; void DisconnectGatt() override;
// This is declared virtual so that they can be overridden by tests.
virtual HRESULT GetBluetoothLEDeviceStaticsActivationFactory(
ABI::Windows::Devices::Bluetooth::IBluetoothLEDeviceStatics** statics)
const;
Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice>
ble_device_;
private: private:
void OnFromBluetoothAddress(
Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice> ble_device);
void OnConnectionStatusChanged(
ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice* ble_device,
IInspectable* object);
void OnGetGattServices(
Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceServicesResult> result);
uint64_t raw_address_;
std::string address_; std::string address_;
base::Optional<std::string> name_; base::Optional<std::string> local_name_;
base::Optional<EventRegistrationToken> connection_changed_token_;
THREAD_CHECKER(thread_checker_);
// Note: This should remain the last member so it'll be destroyed and
// invalidate its weak pointers before any other members are destroyed.
base::WeakPtrFactory<BluetoothDeviceWinrt> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceWinrt); DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceWinrt);
}; };
......
This diff is collapsed.
...@@ -117,8 +117,21 @@ class BluetoothTestWinrt : public BluetoothTestWin, ...@@ -117,8 +117,21 @@ class BluetoothTestWinrt : public BluetoothTestWin,
BluetoothTestWinrt(); BluetoothTestWinrt();
~BluetoothTestWinrt() override; ~BluetoothTestWinrt() override;
// BluetoothTestBase:
bool PlatformSupportsLowEnergy() override; bool PlatformSupportsLowEnergy() override;
void InitWithDefaultAdapter() override;
void InitWithoutDefaultAdapter() override;
void InitWithFakeAdapter() override;
BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal) override; BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal) override;
void SimulateGattConnection(BluetoothDevice* device) override;
void SimulateGattConnectionError(
BluetoothDevice* device,
BluetoothDevice::ConnectErrorCode error_code) override;
void SimulateGattDisconnection(BluetoothDevice* device) override;
void DeleteDevice(BluetoothDevice* device) override;
void OnFakeBluetoothDeviceConnectGattCalled();
void OnFakeBluetoothGattDisconnect();
private: private:
base::test::ScopedFeatureList scoped_feature_list_; base::test::ScopedFeatureList scoped_feature_list_;
......
...@@ -4,28 +4,55 @@ ...@@ -4,28 +4,55 @@
#include "device/bluetooth/test/fake_bluetooth_le_device_winrt.h" #include "device/bluetooth/test/fake_bluetooth_le_device_winrt.h"
#include <wrl/client.h>
#include <utility>
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/win/async_operation.h"
#include "device/bluetooth/test/bluetooth_test_win.h"
#include "device/bluetooth/test/fake_gatt_device_services_result_winrt.h"
namespace device { namespace device {
namespace { namespace {
using ABI::Windows::Devices::Bluetooth::BluetoothCacheMode; using ABI::Windows::Devices::Bluetooth::BluetoothCacheMode;
using ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus; using ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus;
using ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus_Connected;
using ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus_Disconnected;
using ABI::Windows::Devices::Bluetooth::BluetoothLEDevice; using ABI::Windows::Devices::Bluetooth::BluetoothLEDevice;
using ABI::Windows::Devices::Enumeration::DeviceAccessStatus; using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation; GattCommunicationStatus;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus_AccessDenied;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus_ProtocolError;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus_Success;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus_Unreachable;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceService; GattDeviceService;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceServicesResult; GattDeviceServicesResult;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceService; IGattDeviceService;
using ABI::Windows::Devices::Enumeration::DeviceAccessStatus;
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation;
using ABI::Windows::Foundation::Collections::IVectorView; using ABI::Windows::Foundation::Collections::IVectorView;
using ABI::Windows::Foundation::IAsyncOperation; using ABI::Windows::Foundation::IAsyncOperation;
using ABI::Windows::Foundation::ITypedEventHandler; using ABI::Windows::Foundation::ITypedEventHandler;
using Microsoft::WRL::Make;
} // namespace } // namespace
FakeBluetoothLEDeviceWinrt::FakeBluetoothLEDeviceWinrt() = default; FakeBluetoothLEDeviceWinrt::FakeBluetoothLEDeviceWinrt(
BluetoothTestWinrt* bluetooth_test_winrt)
: bluetooth_test_winrt_(bluetooth_test_winrt) {}
FakeBluetoothLEDeviceWinrt::~FakeBluetoothLEDeviceWinrt() = default; FakeBluetoothLEDeviceWinrt::~FakeBluetoothLEDeviceWinrt() = default;
...@@ -44,7 +71,8 @@ HRESULT FakeBluetoothLEDeviceWinrt::get_GattServices( ...@@ -44,7 +71,8 @@ HRESULT FakeBluetoothLEDeviceWinrt::get_GattServices(
HRESULT FakeBluetoothLEDeviceWinrt::get_ConnectionStatus( HRESULT FakeBluetoothLEDeviceWinrt::get_ConnectionStatus(
BluetoothConnectionStatus* value) { BluetoothConnectionStatus* value) {
return E_NOTIMPL; *value = status_;
return S_OK;
} }
HRESULT FakeBluetoothLEDeviceWinrt::get_BluetoothAddress(uint64_t* value) { HRESULT FakeBluetoothLEDeviceWinrt::get_BluetoothAddress(uint64_t* value) {
...@@ -82,12 +110,14 @@ HRESULT FakeBluetoothLEDeviceWinrt::remove_GattServicesChanged( ...@@ -82,12 +110,14 @@ HRESULT FakeBluetoothLEDeviceWinrt::remove_GattServicesChanged(
HRESULT FakeBluetoothLEDeviceWinrt::add_ConnectionStatusChanged( HRESULT FakeBluetoothLEDeviceWinrt::add_ConnectionStatusChanged(
ITypedEventHandler<BluetoothLEDevice*, IInspectable*>* handler, ITypedEventHandler<BluetoothLEDevice*, IInspectable*>* handler,
EventRegistrationToken* token) { EventRegistrationToken* token) {
return E_NOTIMPL; handler_ = handler;
return S_OK;
} }
HRESULT FakeBluetoothLEDeviceWinrt::remove_ConnectionStatusChanged( HRESULT FakeBluetoothLEDeviceWinrt::remove_ConnectionStatusChanged(
EventRegistrationToken token) { EventRegistrationToken token) {
return E_NOTIMPL; handler_ = nullptr;
return S_OK;
} }
HRESULT FakeBluetoothLEDeviceWinrt::get_DeviceAccessInformation( HRESULT FakeBluetoothLEDeviceWinrt::get_DeviceAccessInformation(
...@@ -102,7 +132,11 @@ HRESULT FakeBluetoothLEDeviceWinrt::RequestAccessAsync( ...@@ -102,7 +132,11 @@ HRESULT FakeBluetoothLEDeviceWinrt::RequestAccessAsync(
HRESULT FakeBluetoothLEDeviceWinrt::GetGattServicesAsync( HRESULT FakeBluetoothLEDeviceWinrt::GetGattServicesAsync(
IAsyncOperation<GattDeviceServicesResult*>** operation) { IAsyncOperation<GattDeviceServicesResult*>** operation) {
return E_NOTIMPL; auto async_op = Make<base::win::AsyncOperation<GattDeviceServicesResult*>>();
gatt_services_callback_ = async_op->callback();
*operation = async_op.Detach();
bluetooth_test_winrt_->OnFakeBluetoothDeviceConnectGattCalled();
return S_OK;
} }
HRESULT FakeBluetoothLEDeviceWinrt::GetGattServicesWithCacheModeAsync( HRESULT FakeBluetoothLEDeviceWinrt::GetGattServicesWithCacheModeAsync(
...@@ -124,8 +158,47 @@ HRESULT FakeBluetoothLEDeviceWinrt::GetGattServicesForUuidWithCacheModeAsync( ...@@ -124,8 +158,47 @@ HRESULT FakeBluetoothLEDeviceWinrt::GetGattServicesForUuidWithCacheModeAsync(
return E_NOTIMPL; return E_NOTIMPL;
} }
FakeBluetoothLEDeviceStaticsWinrt::FakeBluetoothLEDeviceStaticsWinrt() = HRESULT FakeBluetoothLEDeviceWinrt::Close() {
default; bluetooth_test_winrt_->OnFakeBluetoothGattDisconnect();
return S_OK;
}
void FakeBluetoothLEDeviceWinrt::SimulateGattConnection() {
if (gatt_services_callback_) {
std::move(gatt_services_callback_)
.Run(Make<FakeGattDeviceServicesResultWinrt>(
GattCommunicationStatus_Success));
}
status_ = BluetoothConnectionStatus_Connected;
handler_->Invoke(this, nullptr);
}
void FakeBluetoothLEDeviceWinrt ::SimulateGattConnectionError(
BluetoothDevice::ConnectErrorCode error_code) {
if (!gatt_services_callback_)
return;
std::move(gatt_services_callback_)
.Run(Make<FakeGattDeviceServicesResultWinrt>(
GattCommunicationStatus_ProtocolError));
}
void FakeBluetoothLEDeviceWinrt::SimulateGattDisconnection() {
if (gatt_services_callback_) {
std::move(gatt_services_callback_)
.Run(Make<FakeGattDeviceServicesResultWinrt>(
GattCommunicationStatus_Unreachable));
return;
}
status_ = BluetoothConnectionStatus_Disconnected;
handler_->Invoke(this, nullptr);
}
FakeBluetoothLEDeviceStaticsWinrt::FakeBluetoothLEDeviceStaticsWinrt(
BluetoothTestWinrt* bluetooth_test_winrt)
: bluetooth_test_winrt_(bluetooth_test_winrt) {}
FakeBluetoothLEDeviceStaticsWinrt::~FakeBluetoothLEDeviceStaticsWinrt() = FakeBluetoothLEDeviceStaticsWinrt::~FakeBluetoothLEDeviceStaticsWinrt() =
default; default;
...@@ -139,7 +212,13 @@ HRESULT FakeBluetoothLEDeviceStaticsWinrt::FromIdAsync( ...@@ -139,7 +212,13 @@ HRESULT FakeBluetoothLEDeviceStaticsWinrt::FromIdAsync(
HRESULT FakeBluetoothLEDeviceStaticsWinrt::FromBluetoothAddressAsync( HRESULT FakeBluetoothLEDeviceStaticsWinrt::FromBluetoothAddressAsync(
uint64_t bluetooth_address, uint64_t bluetooth_address,
IAsyncOperation<BluetoothLEDevice*>** operation) { IAsyncOperation<BluetoothLEDevice*>** operation) {
return E_NOTIMPL; auto async_op = Make<base::win::AsyncOperation<BluetoothLEDevice*>>();
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(async_op->callback(),
Make<FakeBluetoothLEDeviceWinrt>(bluetooth_test_winrt_)));
*operation = async_op.Detach();
return S_OK;
} }
HRESULT FakeBluetoothLEDeviceStaticsWinrt::GetDeviceSelector( HRESULT FakeBluetoothLEDeviceStaticsWinrt::GetDeviceSelector(
......
...@@ -11,18 +11,23 @@ ...@@ -11,18 +11,23 @@
#include <stdint.h> #include <stdint.h>
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "device/bluetooth/bluetooth_device.h"
namespace device { namespace device {
class BluetoothTestWinrt;
class FakeBluetoothLEDeviceWinrt class FakeBluetoothLEDeviceWinrt
: public Microsoft::WRL::RuntimeClass< : public Microsoft::WRL::RuntimeClass<
Microsoft::WRL::RuntimeClassFlags< Microsoft::WRL::RuntimeClassFlags<
Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>, Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice, ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice,
ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice3> { ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice3,
ABI::Windows::Foundation::IClosable> {
public: public:
FakeBluetoothLEDeviceWinrt(); explicit FakeBluetoothLEDeviceWinrt(BluetoothTestWinrt* bluetooth_test_winrt);
~FakeBluetoothLEDeviceWinrt() override; ~FakeBluetoothLEDeviceWinrt() override;
// IBluetoothLEDevice: // IBluetoothLEDevice:
...@@ -90,7 +95,31 @@ class FakeBluetoothLEDeviceWinrt ...@@ -90,7 +95,31 @@ class FakeBluetoothLEDeviceWinrt
ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceServicesResult*>** operation) override; GattDeviceServicesResult*>** operation) override;
// IClosable:
IFACEMETHODIMP Close() override;
void SimulateGattConnection();
void SimulateGattConnectionError(
BluetoothDevice::ConnectErrorCode error_code);
void SimulateGattDisconnection();
private: private:
BluetoothTestWinrt* bluetooth_test_winrt_ = nullptr;
ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus status_ =
ABI::Windows::Devices::Bluetooth::BluetoothConnectionStatus_Connected;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::ITypedEventHandler<
ABI::Windows::Devices::Bluetooth::BluetoothLEDevice*,
IInspectable*>>
handler_;
base::OnceCallback<void(
Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceServicesResult>)>
gatt_services_callback_;
DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEDeviceWinrt); DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEDeviceWinrt);
}; };
...@@ -100,7 +129,8 @@ class FakeBluetoothLEDeviceStaticsWinrt ...@@ -100,7 +129,8 @@ class FakeBluetoothLEDeviceStaticsWinrt
Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>, Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
ABI::Windows::Devices::Bluetooth::IBluetoothLEDeviceStatics> { ABI::Windows::Devices::Bluetooth::IBluetoothLEDeviceStatics> {
public: public:
FakeBluetoothLEDeviceStaticsWinrt(); explicit FakeBluetoothLEDeviceStaticsWinrt(
BluetoothTestWinrt* bluetooth_test_winrt);
~FakeBluetoothLEDeviceStaticsWinrt() override; ~FakeBluetoothLEDeviceStaticsWinrt() override;
// IBluetoothLEDeviceStatics: // IBluetoothLEDeviceStatics:
...@@ -117,6 +147,8 @@ class FakeBluetoothLEDeviceStaticsWinrt ...@@ -117,6 +147,8 @@ class FakeBluetoothLEDeviceStaticsWinrt
IFACEMETHODIMP GetDeviceSelector(HSTRING* device_selector) override; IFACEMETHODIMP GetDeviceSelector(HSTRING* device_selector) override;
private: private:
BluetoothTestWinrt* bluetooth_test_winrt_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEDeviceStaticsWinrt); DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEDeviceStaticsWinrt);
}; };
......
...@@ -17,15 +17,18 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: ...@@ -17,15 +17,18 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
} // namespace } // namespace
FakeGattDeviceServicesResultWinrt::FakeGattDeviceServicesResultWinrt() = FakeGattDeviceServicesResultWinrt::FakeGattDeviceServicesResultWinrt(
default; ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus status)
: status_(status) {}
FakeGattDeviceServicesResultWinrt::~FakeGattDeviceServicesResultWinrt() = FakeGattDeviceServicesResultWinrt::~FakeGattDeviceServicesResultWinrt() =
default; default;
HRESULT FakeGattDeviceServicesResultWinrt::get_Status( HRESULT FakeGattDeviceServicesResultWinrt::get_Status(
GattCommunicationStatus* value) { GattCommunicationStatus* value) {
return E_NOTIMPL; *value = status_;
return S_OK;
} }
HRESULT FakeGattDeviceServicesResultWinrt::get_ProtocolError( HRESULT FakeGattDeviceServicesResultWinrt::get_ProtocolError(
......
...@@ -23,7 +23,9 @@ class FakeGattDeviceServicesResultWinrt ...@@ -23,7 +23,9 @@ class FakeGattDeviceServicesResultWinrt
ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceServicesResult> { IGattDeviceServicesResult> {
public: public:
FakeGattDeviceServicesResultWinrt(); explicit FakeGattDeviceServicesResultWinrt(
ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus status);
~FakeGattDeviceServicesResultWinrt() override; ~FakeGattDeviceServicesResultWinrt() override;
// IGattDeviceServicesResult: // IGattDeviceServicesResult:
...@@ -38,6 +40,9 @@ class FakeGattDeviceServicesResultWinrt ...@@ -38,6 +40,9 @@ class FakeGattDeviceServicesResultWinrt
GattDeviceService*>** value) override; GattDeviceService*>** value) override;
private: private:
ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattCommunicationStatus status_;
DISALLOW_COPY_AND_ASSIGN(FakeGattDeviceServicesResultWinrt); DISALLOW_COPY_AND_ASSIGN(FakeGattDeviceServicesResultWinrt);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment