Commit 8b9a1e07 authored by Jan Wilken Doerrie's avatar Jan Wilken Doerrie Committed by Commit Bot

[Bluetooth][WinRT] Implement Pairing

This change implements pairing on WinRT and adds appropriate tests. In order
to encapsulate the implementation, a new BluetoothPairingWinrt helper class
is introduced. For now only pairing via PIN code is supported.

Bug: 821766
Change-Id: Ic0a64b4e79dd38f9c0ac86a25c0a878f1f70192c
Reviewed-on: https://chromium-review.googlesource.com/1177741
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@{#584391}
parent 5334ca5d
...@@ -250,6 +250,8 @@ component("bluetooth") { ...@@ -250,6 +250,8 @@ component("bluetooth") {
"bluetooth_device_winrt.h", "bluetooth_device_winrt.h",
"bluetooth_gatt_discoverer_winrt.cc", "bluetooth_gatt_discoverer_winrt.cc",
"bluetooth_gatt_discoverer_winrt.h", "bluetooth_gatt_discoverer_winrt.h",
"bluetooth_pairing_winrt.cc",
"bluetooth_pairing_winrt.h",
"bluetooth_remote_gatt_characteristic_winrt.cc", "bluetooth_remote_gatt_characteristic_winrt.cc",
"bluetooth_remote_gatt_characteristic_winrt.h", "bluetooth_remote_gatt_characteristic_winrt.h",
"bluetooth_remote_gatt_descriptor_winrt.cc", "bluetooth_remote_gatt_descriptor_winrt.cc",
......
...@@ -428,7 +428,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDevice { ...@@ -428,7 +428,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDevice {
// ignores the |IsPaired()| value. // ignores the |IsPaired()| value.
// //
// In most cases |Connect()| should be preferred. This method is only // In most cases |Connect()| should be preferred. This method is only
// implemented on ChromeOS and Linux. // implemented on ChromeOS, Linux and Windows 10. On Windows, only pairing
// with a pin code is currently supported.
virtual void Pair(PairingDelegate* pairing_delegate, virtual void Pair(PairingDelegate* pairing_delegate,
const base::Closure& callback, const base::Closure& callback,
const ConnectErrorCallback& error_callback); const ConnectErrorCallback& error_callback);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "device/bluetooth/bluetooth_remote_gatt_service.h" #include "device/bluetooth/bluetooth_remote_gatt_service.h"
#include "device/bluetooth/test/test_bluetooth_adapter_observer.h" #include "device/bluetooth/test/test_bluetooth_adapter_observer.h"
#include "device/bluetooth/test/test_pairing_delegate.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
...@@ -118,6 +119,145 @@ TEST_P(BluetoothTestWinrtOnly, DeviceIsPaired) { ...@@ -118,6 +119,145 @@ TEST_P(BluetoothTestWinrtOnly, DeviceIsPaired) {
SimulateDevicePaired(device, false); SimulateDevicePaired(device, false);
EXPECT_FALSE(device->IsPaired()); EXPECT_FALSE(device->IsPaired());
} }
// Tests that providing a correct pin code results in a paired device.
TEST_P(BluetoothTestWinrtOnly, DevicePairRequestPinCodeCorrect) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
GetConnectErrorCallback(Call::NOT_EXPECTED));
SimulateGattConnection(device);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
SimulatePairingPinCode(device, "123456");
TestPairingDelegate pairing_delegate;
device->Pair(&pairing_delegate, GetCallback(Call::EXPECTED),
GetConnectErrorCallback(Call::NOT_EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, pairing_delegate.call_count_);
EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
EXPECT_TRUE(device->ExpectingPinCode());
device->SetPinCode("123456");
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
}
// Tests that providing a wrong pin code does not result in a paired device.
TEST_P(BluetoothTestWinrtOnly, DevicePairRequestPinCodeWrong) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
GetConnectErrorCallback(Call::NOT_EXPECTED));
SimulateGattConnection(device);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
SimulatePairingPinCode(device, "123456");
TestPairingDelegate pairing_delegate;
device->Pair(&pairing_delegate, GetCallback(Call::NOT_EXPECTED),
GetConnectErrorCallback(Call::EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, pairing_delegate.call_count_);
EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
EXPECT_TRUE(device->ExpectingPinCode());
device->SetPinCode("000000");
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
EXPECT_EQ(BluetoothDevice::ERROR_FAILED, last_connect_error_code_);
}
// Tests that rejecting the pairing does not result in a paired device.
TEST_P(BluetoothTestWinrtOnly, DevicePairRequestPinCodeRejectPairing) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
GetConnectErrorCallback(Call::NOT_EXPECTED));
SimulateGattConnection(device);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
SimulatePairingPinCode(device, "123456");
TestPairingDelegate pairing_delegate;
device->Pair(&pairing_delegate, GetCallback(Call::NOT_EXPECTED),
GetConnectErrorCallback(Call::EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, pairing_delegate.call_count_);
EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
EXPECT_TRUE(device->ExpectingPinCode());
device->RejectPairing();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
EXPECT_EQ(BluetoothDevice::ERROR_AUTH_REJECTED, last_connect_error_code_);
}
// Tests that cancelling the pairing does not result in a paired device.
TEST_P(BluetoothTestWinrtOnly, DevicePairRequestPinCodeCancelPairing) {
if (!PlatformSupportsLowEnergy()) {
LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test.";
return;
}
InitWithFakeAdapter();
StartLowEnergyDiscoverySession();
BluetoothDevice* device = SimulateLowEnergyDevice(1);
device->CreateGattConnection(GetGattConnectionCallback(Call::EXPECTED),
GetConnectErrorCallback(Call::NOT_EXPECTED));
SimulateGattConnection(device);
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
SimulatePairingPinCode(device, "123456");
TestPairingDelegate pairing_delegate;
device->Pair(&pairing_delegate, GetCallback(Call::NOT_EXPECTED),
GetConnectErrorCallback(Call::EXPECTED));
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, pairing_delegate.call_count_);
EXPECT_EQ(1, pairing_delegate.request_pincode_count_);
EXPECT_TRUE(device->ExpectingPinCode());
device->CancelPairing();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(device->IsPaired());
EXPECT_FALSE(device->ExpectingPinCode());
EXPECT_EQ(BluetoothDevice::ERROR_AUTH_CANCELED, last_connect_error_code_);
}
#endif #endif
// Verifies basic device properties, e.g. GetAddress, GetName, ... // Verifies basic device properties, e.g. GetAddress, GetName, ...
......
...@@ -11,12 +11,14 @@ ...@@ -11,12 +11,14 @@
#include "base/bind_helpers.h" #include "base/bind_helpers.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/win/core_winrt_util.h" #include "base/win/core_winrt_util.h"
#include "base/win/scoped_hstring.h" #include "base/win/scoped_hstring.h"
#include "device/bluetooth/bluetooth_adapter_winrt.h" #include "device/bluetooth/bluetooth_adapter_winrt.h"
#include "device/bluetooth/bluetooth_gatt_discoverer_winrt.h" #include "device/bluetooth/bluetooth_gatt_discoverer_winrt.h"
#include "device/bluetooth/bluetooth_pairing_winrt.h"
#include "device/bluetooth/bluetooth_remote_gatt_service_winrt.h" #include "device/bluetooth/bluetooth_remote_gatt_service_winrt.h"
#include "device/bluetooth/event_utils_winrt.h" #include "device/bluetooth/event_utils_winrt.h"
...@@ -35,17 +37,69 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: ...@@ -35,17 +37,69 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceServicesResult; GattDeviceServicesResult;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceServicesResult; IGattDeviceServicesResult;
using ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice;
using ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice2; using ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice2;
using ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice3; using ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice3;
using ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice;
using ABI::Windows::Devices::Bluetooth::IBluetoothLEDeviceStatics; using ABI::Windows::Devices::Bluetooth::IBluetoothLEDeviceStatics;
using ABI::Windows::Devices::Enumeration::IDeviceInformation; using ABI::Windows::Devices::Enumeration::DevicePairingResultStatus;
using ABI::Windows::Devices::Enumeration::IDeviceInformation2; using ABI::Windows::Devices::Enumeration::IDeviceInformation2;
using ABI::Windows::Devices::Enumeration::IDeviceInformation;
using ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing;
using ABI::Windows::Devices::Enumeration::IDeviceInformationPairing2;
using ABI::Windows::Devices::Enumeration::IDeviceInformationPairing; using ABI::Windows::Devices::Enumeration::IDeviceInformationPairing;
using ABI::Windows::Devices::Enumeration::IDevicePairingRequestedEventArgs;
using ABI::Windows::Foundation::IAsyncOperation; using ABI::Windows::Foundation::IAsyncOperation;
using ABI::Windows::Foundation::IClosable; using ABI::Windows::Foundation::IClosable;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
void PostTask(BluetoothPairingWinrt::ErrorCallback error_callback,
BluetoothDevice::ConnectErrorCode error_code) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(error_callback), error_code));
}
ComPtr<IDeviceInformationPairing> GetDeviceInformationPairing(
ComPtr<IBluetoothLEDevice> ble_device) {
if (!ble_device) {
VLOG(2) << "No BLE device instance present.";
return nullptr;
}
ComPtr<IBluetoothLEDevice2> ble_device_2;
HRESULT hr = ble_device.As(&ble_device_2);
if (FAILED(hr)) {
VLOG(2) << "Obtaining IBluetoothLEDevice2 failed: "
<< logging::SystemErrorCodeToString(hr);
return nullptr;
}
ComPtr<IDeviceInformation> device_information;
hr = ble_device_2->get_DeviceInformation(&device_information);
if (FAILED(hr)) {
VLOG(2) << "Getting Device Information failed: "
<< logging::SystemErrorCodeToString(hr);
return nullptr;
}
ComPtr<IDeviceInformation2> device_information_2;
hr = device_information.As(&device_information_2);
if (FAILED(hr)) {
VLOG(2) << "Obtaining IDeviceInformation2 failed: "
<< logging::SystemErrorCodeToString(hr);
return nullptr;
}
ComPtr<IDeviceInformationPairing> pairing;
hr = device_information_2->get_Pairing(&pairing);
if (FAILED(hr)) {
VLOG(2) << "DeviceInformation::get_Pairing() failed: "
<< logging::SystemErrorCodeToString(hr);
return nullptr;
}
return pairing;
}
void CloseDevice(ComPtr<IBluetoothLEDevice> ble_device) { void CloseDevice(ComPtr<IBluetoothLEDevice> ble_device) {
if (!ble_device) if (!ble_device)
return; return;
...@@ -152,45 +206,15 @@ base::Optional<std::string> BluetoothDeviceWinrt::GetName() const { ...@@ -152,45 +206,15 @@ base::Optional<std::string> BluetoothDeviceWinrt::GetName() const {
} }
bool BluetoothDeviceWinrt::IsPaired() const { bool BluetoothDeviceWinrt::IsPaired() const {
if (!ble_device_) { ComPtr<IDeviceInformationPairing> pairing =
VLOG(2) << "No BLE device instance present."; GetDeviceInformationPairing(ble_device_);
return false; if (!pairing) {
} VLOG(2) << "Failed to get DeviceInformationPairing.";
ComPtr<IBluetoothLEDevice2> ble_device_2;
HRESULT hr = ble_device_.As(&ble_device_2);
if (FAILED(hr)) {
VLOG(2) << "Obtaining IBluetoothLEDevice2 failed: "
<< logging::SystemErrorCodeToString(hr);
return false;
}
ComPtr<IDeviceInformation> device_information;
hr = ble_device_2->get_DeviceInformation(&device_information);
if (FAILED(hr)) {
VLOG(2) << "Getting Device Information failed: "
<< logging::SystemErrorCodeToString(hr);
return false;
}
ComPtr<IDeviceInformation2> device_information_2;
hr = device_information.As(&device_information_2);
if (FAILED(hr)) {
VLOG(2) << "Obtaining IDeviceInformation2 failed: "
<< logging::SystemErrorCodeToString(hr);
return false;
}
ComPtr<IDeviceInformationPairing> pairing;
hr = device_information_2->get_Pairing(&pairing);
if (FAILED(hr)) {
VLOG(2) << "DeviceInformation::get_Pairing() failed: "
<< logging::SystemErrorCodeToString(hr);
return false; return false;
} }
boolean is_paired; boolean is_paired;
hr = pairing->get_IsPaired(&is_paired); HRESULT hr = pairing->get_IsPaired(&is_paired);
if (FAILED(hr)) { if (FAILED(hr)) {
VLOG(2) << "DeviceInformationPairing::get_IsPaired() failed: " VLOG(2) << "DeviceInformationPairing::get_IsPaired() failed: "
<< logging::SystemErrorCodeToString(hr); << logging::SystemErrorCodeToString(hr);
...@@ -232,8 +256,7 @@ bool BluetoothDeviceWinrt::IsConnecting() const { ...@@ -232,8 +256,7 @@ bool BluetoothDeviceWinrt::IsConnecting() const {
} }
bool BluetoothDeviceWinrt::ExpectingPinCode() const { bool BluetoothDeviceWinrt::ExpectingPinCode() const {
NOTIMPLEMENTED(); return pairing_ && pairing_->ExpectingPinCode();
return false;
} }
bool BluetoothDeviceWinrt::ExpectingPasskey() const { bool BluetoothDeviceWinrt::ExpectingPasskey() const {
...@@ -264,8 +287,71 @@ void BluetoothDeviceWinrt::Connect(PairingDelegate* pairing_delegate, ...@@ -264,8 +287,71 @@ void BluetoothDeviceWinrt::Connect(PairingDelegate* pairing_delegate,
NOTIMPLEMENTED(); NOTIMPLEMENTED();
} }
void BluetoothDeviceWinrt::Pair(PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) {
VLOG(2) << "BluetoothDeviceWinrt::Pair()";
if (pairing_) {
VLOG(2) << "Another Pair Operation is already in progress.";
PostTask(error_callback, ERROR_INPROGRESS);
return;
}
ComPtr<IDeviceInformationPairing> pairing =
GetDeviceInformationPairing(ble_device_);
if (!pairing) {
VLOG(2) << "Failed to get DeviceInformationPairing.";
PostTask(error_callback, ERROR_UNKNOWN);
return;
}
ComPtr<IDeviceInformationPairing2> pairing_2;
HRESULT hr = pairing.As(&pairing_2);
if (FAILED(hr)) {
VLOG(2) << "Obtaining IDeviceInformationPairing2 failed: "
<< logging::SystemErrorCodeToString(hr);
PostTask(error_callback, ERROR_UNKNOWN);
return;
}
ComPtr<IDeviceInformationCustomPairing> custom;
hr = pairing_2->get_Custom(&custom);
if (FAILED(hr)) {
VLOG(2) << "DeviceInformationPairing::get_Custom() failed: "
<< logging::SystemErrorCodeToString(hr);
PostTask(error_callback, ERROR_UNKNOWN);
return;
}
// Wrap success and error callback, so that they clean up the pairing object
// once they are run.
auto wrapped_callback = base::BindOnce(
[](base::WeakPtr<BluetoothDeviceWinrt> device,
base::OnceClosure callback) {
if (device)
device->pairing_.reset();
std::move(callback).Run();
},
weak_ptr_factory_.GetWeakPtr(), callback);
auto wrapped_error_callback = base::BindOnce(
[](base::WeakPtr<BluetoothDeviceWinrt> device,
ConnectErrorCallback error_callback, ConnectErrorCode error_code) {
if (device)
device->pairing_.reset();
std::move(error_callback).Run(error_code);
},
weak_ptr_factory_.GetWeakPtr(), error_callback);
pairing_ = std::make_unique<BluetoothPairingWinrt>(
this, pairing_delegate, std::move(custom), std::move(wrapped_callback),
std::move(wrapped_error_callback));
pairing_->StartPairing();
}
void BluetoothDeviceWinrt::SetPinCode(const std::string& pincode) { void BluetoothDeviceWinrt::SetPinCode(const std::string& pincode) {
NOTIMPLEMENTED(); if (pairing_)
pairing_->SetPinCode(pincode);
} }
void BluetoothDeviceWinrt::SetPasskey(uint32_t passkey) { void BluetoothDeviceWinrt::SetPasskey(uint32_t passkey) {
...@@ -277,11 +363,13 @@ void BluetoothDeviceWinrt::ConfirmPairing() { ...@@ -277,11 +363,13 @@ void BluetoothDeviceWinrt::ConfirmPairing() {
} }
void BluetoothDeviceWinrt::RejectPairing() { void BluetoothDeviceWinrt::RejectPairing() {
NOTIMPLEMENTED(); if (pairing_)
pairing_->RejectPairing();
} }
void BluetoothDeviceWinrt::CancelPairing() { void BluetoothDeviceWinrt::CancelPairing() {
NOTIMPLEMENTED(); if (pairing_)
pairing_->CancelPairing();
} }
void BluetoothDeviceWinrt::Disconnect(const base::Closure& callback, void BluetoothDeviceWinrt::Disconnect(const base::Closure& callback,
......
...@@ -25,6 +25,7 @@ namespace device { ...@@ -25,6 +25,7 @@ namespace device {
class BluetoothAdapterWinrt; class BluetoothAdapterWinrt;
class BluetoothGattDiscovererWinrt; class BluetoothGattDiscovererWinrt;
class BluetoothPairingWinrt;
class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice { class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice {
public: public:
...@@ -65,6 +66,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice { ...@@ -65,6 +66,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice {
void Connect(PairingDelegate* pairing_delegate, void Connect(PairingDelegate* pairing_delegate,
const base::Closure& callback, const base::Closure& callback,
const ConnectErrorCallback& error_callback) override; const ConnectErrorCallback& error_callback) override;
void Pair(PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) override;
void SetPinCode(const std::string& pincode) override; void SetPinCode(const std::string& pincode) override;
void SetPasskey(uint32_t passkey) override; void SetPasskey(uint32_t passkey) override;
void ConfirmPairing() override; void ConfirmPairing() override;
...@@ -115,10 +119,18 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice { ...@@ -115,10 +119,18 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWinrt : public BluetoothDevice {
void OnGattDiscoveryComplete(bool success); void OnGattDiscoveryComplete(bool success);
void OnPairingRequested(
ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing*
custom_pairing,
ABI::Windows::Devices::Enumeration::IDevicePairingRequestedEventArgs*
event_args);
uint64_t raw_address_; uint64_t raw_address_;
std::string address_; std::string address_;
base::Optional<std::string> local_name_; base::Optional<std::string> local_name_;
std::unique_ptr<BluetoothPairingWinrt> pairing_;
std::unique_ptr<BluetoothGattDiscovererWinrt> gatt_discoverer_; std::unique_ptr<BluetoothGattDiscovererWinrt> gatt_discoverer_;
base::Optional<EventRegistrationToken> connection_changed_token_; base::Optional<EventRegistrationToken> connection_changed_token_;
......
// Copyright 2018 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 "device/bluetooth/bluetooth_pairing_winrt.h"
#include <utility>
#include "base/logging.h"
#include "base/strings/string_piece.h"
#include "base/win/scoped_hstring.h"
#include "device/bluetooth/bluetooth_device_winrt.h"
#include "device/bluetooth/event_utils_winrt.h"
namespace device {
namespace {
using ABI::Windows::Devices::Enumeration::DevicePairingKinds;
using ABI::Windows::Devices::Enumeration::DevicePairingKinds_ProvidePin;
using ABI::Windows::Devices::Enumeration::DevicePairingResult;
using ABI::Windows::Devices::Enumeration::DevicePairingResultStatus;
using ABI::Windows::Devices::Enumeration::
DevicePairingResultStatus_AuthenticationFailure;
using ABI::Windows::Devices::Enumeration::
DevicePairingResultStatus_AuthenticationTimeout;
using ABI::Windows::Devices::Enumeration::
DevicePairingResultStatus_ConnectionRejected;
using ABI::Windows::Devices::Enumeration::
DevicePairingResultStatus_AlreadyPaired;
using ABI::Windows::Devices::Enumeration::DevicePairingResultStatus_Failed;
using ABI::Windows::Devices::Enumeration::
DevicePairingResultStatus_OperationAlreadyInProgress;
using ABI::Windows::Devices::Enumeration::DevicePairingResultStatus_Paired;
using ABI::Windows::Devices::Enumeration::
DevicePairingResultStatus_PairingCanceled;
using ABI::Windows::Devices::Enumeration::
DevicePairingResultStatus_RejectedByHandler;
using ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing;
using ABI::Windows::Devices::Enumeration::IDevicePairingRequestedEventArgs;
using ABI::Windows::Devices::Enumeration::IDevicePairingResult;
using ABI::Windows::Foundation::IAsyncOperation;
using Microsoft::WRL::ComPtr;
void PostTask(BluetoothPairingWinrt::ErrorCallback error_callback,
BluetoothDevice::ConnectErrorCode error_code) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(error_callback), error_code));
}
} // namespace
BluetoothPairingWinrt::BluetoothPairingWinrt(
BluetoothDeviceWinrt* device,
BluetoothDevice::PairingDelegate* pairing_delegate,
ComPtr<IDeviceInformationCustomPairing> custom_pairing,
Callback callback,
ErrorCallback error_callback)
: device_(device),
pairing_delegate_(pairing_delegate),
custom_pairing_(std::move(custom_pairing)),
callback_(std::move(callback)),
error_callback_(std::move(error_callback)),
weak_ptr_factory_(this) {
DCHECK(device_);
DCHECK(pairing_delegate_);
DCHECK(custom_pairing_);
}
BluetoothPairingWinrt::~BluetoothPairingWinrt() {
if (!pairing_requested_token_)
return;
HRESULT hr =
custom_pairing_->remove_PairingRequested(*pairing_requested_token_);
if (FAILED(hr)) {
VLOG(2) << "Removing PairingRequested Handler failed: "
<< logging::SystemErrorCodeToString(hr);
}
}
void BluetoothPairingWinrt::StartPairing() {
pairing_requested_token_ = AddTypedEventHandler(
custom_pairing_.Get(),
&IDeviceInformationCustomPairing::add_PairingRequested,
base::BindRepeating(&BluetoothPairingWinrt::OnPairingRequested,
weak_ptr_factory_.GetWeakPtr()));
if (!pairing_requested_token_) {
PostTask(std::move(error_callback_),
BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
ComPtr<IAsyncOperation<DevicePairingResult*>> pair_op;
HRESULT hr =
custom_pairing_->PairAsync(DevicePairingKinds_ProvidePin, &pair_op);
if (FAILED(hr)) {
VLOG(2) << "DeviceInformationCustomPairing::PairAsync() failed: "
<< logging::SystemErrorCodeToString(hr);
PostTask(std::move(error_callback_),
BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
hr = PostAsyncResults(std::move(pair_op),
base::BindOnce(&BluetoothPairingWinrt::OnPair,
weak_ptr_factory_.GetWeakPtr()));
if (FAILED(hr)) {
VLOG(2) << "PostAsyncResults failed: "
<< logging::SystemErrorCodeToString(hr);
PostTask(std::move(error_callback_),
BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
}
bool BluetoothPairingWinrt::ExpectingPinCode() const {
return expecting_pin_code_;
}
void BluetoothPairingWinrt::SetPinCode(base::StringPiece pin_code) {
VLOG(2) << "BluetoothPairingWinrt::SetPinCode(" << pin_code << ")";
auto pin_hstring = base::win::ScopedHString::Create(pin_code);
DCHECK(expecting_pin_code_);
expecting_pin_code_ = false;
DCHECK(pairing_requested_);
HRESULT hr = pairing_requested_->AcceptWithPin(pin_hstring.get());
if (FAILED(hr)) {
VLOG(2) << "Accepting Pairing Request With Pin failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
DCHECK(pairing_deferral_);
hr = pairing_deferral_->Complete();
if (FAILED(hr)) {
VLOG(2) << "Completing Deferred Pairing Request failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
}
}
void BluetoothPairingWinrt::RejectPairing() {
VLOG(2) << "BluetoothPairingWinrt::RejectPairing()";
DCHECK(pairing_deferral_);
HRESULT hr = pairing_deferral_->Complete();
if (FAILED(hr)) {
VLOG(2) << "Completing Deferred Pairing Request failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED);
}
void BluetoothPairingWinrt::CancelPairing() {
VLOG(2) << "BluetoothPairingWinrt::CancelPairing()";
DCHECK(pairing_deferral_);
HRESULT hr = pairing_deferral_->Complete();
if (FAILED(hr)) {
VLOG(2) << "Completing Deferred Pairing Request failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_CANCELED);
}
void BluetoothPairingWinrt::OnPairingRequested(
IDeviceInformationCustomPairing* custom_pairing,
IDevicePairingRequestedEventArgs* pairing_requested) {
VLOG(2) << "BluetoothPairingWinrt::OnPairingRequested()";
DevicePairingKinds pairing_kind;
HRESULT hr = pairing_requested->get_PairingKind(&pairing_kind);
if (FAILED(hr)) {
VLOG(2) << "Getting Pairing Kind failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
VLOG(2) << "DevicePairingKind: " << static_cast<int>(pairing_kind);
if (pairing_kind != DevicePairingKinds_ProvidePin) {
VLOG(2) << "Unexpected DevicePairingKind.";
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
hr = pairing_requested->GetDeferral(&pairing_deferral_);
if (FAILED(hr)) {
VLOG(2) << "Getting Pairing Deferral failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
pairing_requested_ = pairing_requested;
expecting_pin_code_ = true;
pairing_delegate_->RequestPinCode(device_);
}
void BluetoothPairingWinrt::OnPair(
ComPtr<IDevicePairingResult> pairing_result) {
DevicePairingResultStatus status;
HRESULT hr = pairing_result->get_Status(&status);
if (FAILED(hr)) {
VLOG(2) << "Getting Pairing Result Status failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
VLOG(2) << "Pairing Result Status: " << static_cast<int>(status);
switch (status) {
case DevicePairingResultStatus_AlreadyPaired:
case DevicePairingResultStatus_Paired:
std::move(callback_).Run();
return;
case DevicePairingResultStatus_PairingCanceled:
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_CANCELED);
return;
case DevicePairingResultStatus_AuthenticationFailure:
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_FAILED);
return;
case DevicePairingResultStatus_ConnectionRejected:
case DevicePairingResultStatus_RejectedByHandler:
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED);
return;
case DevicePairingResultStatus_AuthenticationTimeout:
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_AUTH_TIMEOUT);
return;
case DevicePairingResultStatus_Failed:
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
case DevicePairingResultStatus_OperationAlreadyInProgress:
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_INPROGRESS);
return;
default:
std::move(error_callback_)
.Run(BluetoothDevice::ConnectErrorCode::ERROR_FAILED);
return;
}
}
} // namespace device
// Copyright 2018 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.
#ifndef DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_WINRT_H_
#define DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_WINRT_H_
#include <windows.devices.enumeration.h>
#include <windows.foundation.h>
#include <wrl/client.h>
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_piece_forward.h"
#include "device/bluetooth/bluetooth_device.h"
namespace device {
class BluetoothDeviceWinrt;
// This class encapsulates logic required to perform a custom pairing on WinRT.
// Currently only pairing with a pin code is supported.
class BluetoothPairingWinrt {
public:
using Callback = base::OnceClosure;
using ErrorCallback =
base::OnceCallback<void(BluetoothDevice::ConnectErrorCode)>;
BluetoothPairingWinrt(
BluetoothDeviceWinrt* device,
BluetoothDevice::PairingDelegate* pairing_delegate,
Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing>
custom_pairing,
Callback callback,
ErrorCallback error_callback);
~BluetoothPairingWinrt();
// Initiates the pairing procedure.
void StartPairing();
// Indicates whether the device is currently pairing and expecting a
// PIN Code to be returned.
bool ExpectingPinCode() const;
// Sends the PIN code |pin_code| to the remote device during pairing.
void SetPinCode(base::StringPiece pin_code);
// Rejects a pairing or connection request from a remote device.
void RejectPairing();
// Cancels a pairing or connection attempt to a remote device.
void CancelPairing();
private:
void OnPairingRequested(
ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing*
custom_pairing,
ABI::Windows::Devices::Enumeration::IDevicePairingRequestedEventArgs*
pairing_requested);
void OnPair(Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Enumeration::IDevicePairingResult>
pairing_result);
// Weak. This is the device object that owns this pairing instance.
BluetoothDeviceWinrt* device_;
// Weak. This is the pairing delegate provided to BluetoothDevice::Pair.
// Clients need to ensure the delegate stays alive during the pairing
// procedure.
BluetoothDevice::PairingDelegate* pairing_delegate_;
// Boolean indicating whether the device is currently pairing and expecting a
// PIN Code to be returned.
bool expecting_pin_code_ = false;
Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing>
custom_pairing_;
Callback callback_;
ErrorCallback error_callback_;
base::Optional<EventRegistrationToken> pairing_requested_token_;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::IDeferral> pairing_deferral_;
Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Enumeration::IDevicePairingRequestedEventArgs>
pairing_requested_;
base::WeakPtrFactory<BluetoothPairingWinrt> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(BluetoothPairingWinrt);
};
} // namespace device
#endif // DEVICE_BLUETOOTH_BLUETOOTH_PAIRING_WINRT_H_
...@@ -251,6 +251,10 @@ class BluetoothTestBase : public testing::Test { ...@@ -251,6 +251,10 @@ class BluetoothTestBase : public testing::Test {
// Simulates a change in |device|'s pairing state. // Simulates a change in |device|'s pairing state.
virtual void SimulateDevicePaired(BluetoothDevice* device, bool is_paired) {} virtual void SimulateDevicePaired(BluetoothDevice* device, bool is_paired) {}
// Sets |device|'s pairing code to |pin_code|.
virtual void SimulatePairingPinCode(BluetoothDevice* device,
std::string pin_code) {}
// Remembers |device|'s platform specific object to be used in a // Remembers |device|'s platform specific object to be used in a
// subsequent call to methods such as SimulateGattServicesDiscovered that // subsequent call to methods such as SimulateGattServicesDiscovered that
// accept a nullptr value to select this remembered characteristic. This // accept a nullptr value to select this remembered characteristic. This
......
...@@ -682,6 +682,14 @@ void BluetoothTestWinrt::SimulateDevicePaired(BluetoothDevice* device, ...@@ -682,6 +682,14 @@ void BluetoothTestWinrt::SimulateDevicePaired(BluetoothDevice* device,
ble_device->SimulateDevicePaired(is_paired); ble_device->SimulateDevicePaired(is_paired);
} }
void BluetoothTestWinrt::SimulatePairingPinCode(BluetoothDevice* device,
std::string pin_code) {
auto* const ble_device =
static_cast<TestBluetoothDeviceWinrt*>(device)->ble_device();
DCHECK(ble_device);
ble_device->SimulatePairingPinCode(std::move(pin_code));
}
void BluetoothTestWinrt::SimulateGattConnection(BluetoothDevice* device) { void BluetoothTestWinrt::SimulateGattConnection(BluetoothDevice* device) {
if (!GetParam() || !PlatformSupportsLowEnergy()) if (!GetParam() || !PlatformSupportsLowEnergy())
return BluetoothTestWin::SimulateGattConnection(device); return BluetoothTestWin::SimulateGattConnection(device);
......
...@@ -123,6 +123,8 @@ class BluetoothTestWinrt : public BluetoothTestWin, ...@@ -123,6 +123,8 @@ class BluetoothTestWinrt : public BluetoothTestWin,
void InitWithFakeAdapter() override; void InitWithFakeAdapter() override;
BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal) override; BluetoothDevice* SimulateLowEnergyDevice(int device_ordinal) override;
void SimulateDevicePaired(BluetoothDevice* device, bool is_paired) override; void SimulateDevicePaired(BluetoothDevice* device, bool is_paired) override;
void SimulatePairingPinCode(BluetoothDevice* device,
std::string pin_code) override;
void SimulateGattConnection(BluetoothDevice* device) override; void SimulateGattConnection(BluetoothDevice* device) override;
void SimulateGattConnectionError( void SimulateGattConnectionError(
BluetoothDevice* device, BluetoothDevice* device,
......
...@@ -192,6 +192,11 @@ void FakeBluetoothLEDeviceWinrt::SimulateDevicePaired(bool is_paired) { ...@@ -192,6 +192,11 @@ void FakeBluetoothLEDeviceWinrt::SimulateDevicePaired(bool is_paired) {
Make<FakeDeviceInformationPairingWinrt>(is_paired)); Make<FakeDeviceInformationPairingWinrt>(is_paired));
} }
void FakeBluetoothLEDeviceWinrt::SimulatePairingPinCode(std::string pin_code) {
device_information_ = Make<FakeDeviceInformationWinrt>(
Make<FakeDeviceInformationPairingWinrt>(std::move(pin_code)));
}
void FakeBluetoothLEDeviceWinrt::SimulateGattConnection() { void FakeBluetoothLEDeviceWinrt::SimulateGattConnection() {
status_ = BluetoothConnectionStatus_Connected; status_ = BluetoothConnectionStatus_Connected;
connection_status_changed_handler_->Invoke(this, nullptr); connection_status_changed_handler_->Invoke(this, nullptr);
......
...@@ -115,6 +115,7 @@ class FakeBluetoothLEDeviceWinrt ...@@ -115,6 +115,7 @@ class FakeBluetoothLEDeviceWinrt
IFACEMETHODIMP Close() override; IFACEMETHODIMP Close() override;
void SimulateDevicePaired(bool is_paired); void SimulateDevicePaired(bool is_paired);
void SimulatePairingPinCode(std::string pin_code);
void SimulateGattConnection(); void SimulateGattConnection();
void SimulateGattConnectionError( void SimulateGattConnectionError(
BluetoothDevice::ConnectErrorCode error_code); BluetoothDevice::ConnectErrorCode error_code);
......
...@@ -6,6 +6,14 @@ ...@@ -6,6 +6,14 @@
#include <windows.foundation.h> #include <windows.foundation.h>
#include <utility>
#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/fake_device_pairing_requested_event_args_winrt.h"
#include "device/bluetooth/test/fake_device_pairing_result_winrt.h"
namespace device { namespace device {
namespace { namespace {
...@@ -15,14 +23,22 @@ using ABI::Windows::Devices::Enumeration::DevicePairingKinds; ...@@ -15,14 +23,22 @@ using ABI::Windows::Devices::Enumeration::DevicePairingKinds;
using ABI::Windows::Devices::Enumeration::DevicePairingProtectionLevel; using ABI::Windows::Devices::Enumeration::DevicePairingProtectionLevel;
using ABI::Windows::Devices::Enumeration::DevicePairingRequestedEventArgs; using ABI::Windows::Devices::Enumeration::DevicePairingRequestedEventArgs;
using ABI::Windows::Devices::Enumeration::DevicePairingResult; using ABI::Windows::Devices::Enumeration::DevicePairingResult;
using ABI::Windows::Devices::Enumeration::DevicePairingResultStatus_Failed;
using ABI::Windows::Devices::Enumeration::DevicePairingResultStatus_Paired;
using ABI::Windows::Devices::Enumeration::IDevicePairingResult;
using ABI::Windows::Devices::Enumeration::IDevicePairingSettings; using ABI::Windows::Devices::Enumeration::IDevicePairingSettings;
using ABI::Windows::Foundation::IAsyncOperation; using ABI::Windows::Foundation::IAsyncOperation;
using ABI::Windows::Foundation::ITypedEventHandler; using ABI::Windows::Foundation::ITypedEventHandler;
using Microsoft::WRL::ComPtr;
using Microsoft::WRL::Make;
} // namespace } // namespace
FakeDeviceInformationCustomPairingWinrt:: FakeDeviceInformationCustomPairingWinrt::
FakeDeviceInformationCustomPairingWinrt() = default; FakeDeviceInformationCustomPairingWinrt(
Microsoft::WRL::ComPtr<FakeDeviceInformationPairingWinrt> pairing,
std::string pin)
: pairing_(std::move(pairing)), pin_(std::move(pin)) {}
FakeDeviceInformationCustomPairingWinrt:: FakeDeviceInformationCustomPairingWinrt::
~FakeDeviceInformationCustomPairingWinrt() = default; ~FakeDeviceInformationCustomPairingWinrt() = default;
...@@ -30,7 +46,19 @@ FakeDeviceInformationCustomPairingWinrt:: ...@@ -30,7 +46,19 @@ FakeDeviceInformationCustomPairingWinrt::
HRESULT FakeDeviceInformationCustomPairingWinrt::PairAsync( HRESULT FakeDeviceInformationCustomPairingWinrt::PairAsync(
DevicePairingKinds pairing_kinds_supported, DevicePairingKinds pairing_kinds_supported,
IAsyncOperation<DevicePairingResult*>** result) { IAsyncOperation<DevicePairingResult*>** result) {
return E_NOTIMPL; if (!pairing_requested_handler_)
return E_FAIL;
auto async_op = Make<base::win::AsyncOperation<DevicePairingResult*>>();
pair_callback_ = async_op->callback();
*result = async_op.Detach();
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindLambdaForTesting([this] {
pairing_requested_handler_->Invoke(
this, Make<FakeDevicePairingRequestedEventArgsWinrt>(this).Get());
}));
return S_OK;
} }
HRESULT FakeDeviceInformationCustomPairingWinrt::PairWithProtectionLevelAsync( HRESULT FakeDeviceInformationCustomPairingWinrt::PairWithProtectionLevelAsync(
...@@ -53,12 +81,35 @@ HRESULT FakeDeviceInformationCustomPairingWinrt::add_PairingRequested( ...@@ -53,12 +81,35 @@ HRESULT FakeDeviceInformationCustomPairingWinrt::add_PairingRequested(
ITypedEventHandler<DeviceInformationCustomPairing*, ITypedEventHandler<DeviceInformationCustomPairing*,
DevicePairingRequestedEventArgs*>* handler, DevicePairingRequestedEventArgs*>* handler,
EventRegistrationToken* token) { EventRegistrationToken* token) {
return E_NOTIMPL; pairing_requested_handler_ = handler;
return S_OK;
} }
HRESULT FakeDeviceInformationCustomPairingWinrt::remove_PairingRequested( HRESULT FakeDeviceInformationCustomPairingWinrt::remove_PairingRequested(
EventRegistrationToken token) { EventRegistrationToken token) {
return E_NOTIMPL; pairing_requested_handler_.Reset();
return S_OK;
}
void FakeDeviceInformationCustomPairingWinrt::AcceptWithPin(std::string pin) {
accepted_pin_ = std::move(pin);
}
void FakeDeviceInformationCustomPairingWinrt::Complete() {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
base::BindOnce(
[](base::OnceCallback<void(ComPtr<IDevicePairingResult>)>
pair_callback,
ComPtr<FakeDeviceInformationPairingWinrt> pairing,
bool is_paired) {
std::move(pair_callback)
.Run(Make<FakeDevicePairingResultWinrt>(
is_paired ? DevicePairingResultStatus_Paired
: DevicePairingResultStatus_Failed));
pairing->set_paired(is_paired);
},
std::move(pair_callback_), pairing_, pin_ == accepted_pin_));
} }
} // namespace device } // namespace device
...@@ -6,9 +6,14 @@ ...@@ -6,9 +6,14 @@
#define DEVICE_BLUETOOTH_TEST_FAKE_DEVICE_INFORMATION_CUSTOM_PAIRING_WINRT_H_ #define DEVICE_BLUETOOTH_TEST_FAKE_DEVICE_INFORMATION_CUSTOM_PAIRING_WINRT_H_
#include <windows.devices.enumeration.h> #include <windows.devices.enumeration.h>
#include <wrl/client.h>
#include <wrl/implements.h> #include <wrl/implements.h>
#include <string>
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "device/bluetooth/test/fake_device_information_pairing_winrt.h"
namespace device { namespace device {
...@@ -18,7 +23,9 @@ class FakeDeviceInformationCustomPairingWinrt ...@@ -18,7 +23,9 @@ class FakeDeviceInformationCustomPairingWinrt
Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>, Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing> { ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing> {
public: public:
FakeDeviceInformationCustomPairingWinrt(); FakeDeviceInformationCustomPairingWinrt(
Microsoft::WRL::ComPtr<FakeDeviceInformationPairingWinrt> pairing,
std::string pin);
~FakeDeviceInformationCustomPairingWinrt() override; ~FakeDeviceInformationCustomPairingWinrt() override;
// IDeviceInformationCustomPairing: // IDeviceInformationCustomPairing:
...@@ -54,7 +61,24 @@ class FakeDeviceInformationCustomPairingWinrt ...@@ -54,7 +61,24 @@ class FakeDeviceInformationCustomPairingWinrt
EventRegistrationToken* token) override; EventRegistrationToken* token) override;
IFACEMETHODIMP remove_PairingRequested(EventRegistrationToken token) override; IFACEMETHODIMP remove_PairingRequested(EventRegistrationToken token) override;
void AcceptWithPin(std::string pin);
void Complete();
private: private:
Microsoft::WRL::ComPtr<FakeDeviceInformationPairingWinrt> pairing_;
std::string pin_;
std::string accepted_pin_;
base::OnceCallback<void(
Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Enumeration::IDevicePairingResult>)>
pair_callback_;
Microsoft::WRL::ComPtr<ABI::Windows::Foundation::ITypedEventHandler<
ABI::Windows::Devices::Enumeration::DeviceInformationCustomPairing*,
ABI::Windows::Devices::Enumeration::DevicePairingRequestedEventArgs*>>
pairing_requested_handler_;
DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationCustomPairingWinrt); DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationCustomPairingWinrt);
}; };
......
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
#include "device/bluetooth/test/fake_device_information_pairing_winrt.h" #include "device/bluetooth/test/fake_device_information_pairing_winrt.h"
#include <utility>
#include "device/bluetooth/test/fake_device_information_custom_pairing_winrt.h"
namespace device { namespace device {
namespace { namespace {
...@@ -14,6 +18,7 @@ using ABI::Windows::Devices::Enumeration::DeviceUnpairingResult; ...@@ -14,6 +18,7 @@ using ABI::Windows::Devices::Enumeration::DeviceUnpairingResult;
using ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing; using ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing;
using ABI::Windows::Devices::Enumeration::IDevicePairingSettings; using ABI::Windows::Devices::Enumeration::IDevicePairingSettings;
using ABI::Windows::Foundation::IAsyncOperation; using ABI::Windows::Foundation::IAsyncOperation;
using Microsoft::WRL::Make;
} // namespace } // namespace
...@@ -21,6 +26,11 @@ FakeDeviceInformationPairingWinrt::FakeDeviceInformationPairingWinrt( ...@@ -21,6 +26,11 @@ FakeDeviceInformationPairingWinrt::FakeDeviceInformationPairingWinrt(
bool is_paired) bool is_paired)
: is_paired_(is_paired) {} : is_paired_(is_paired) {}
FakeDeviceInformationPairingWinrt::FakeDeviceInformationPairingWinrt(
std::string pin)
: custom_(Make<FakeDeviceInformationCustomPairingWinrt>(this,
std::move(pin))) {}
FakeDeviceInformationPairingWinrt::~FakeDeviceInformationPairingWinrt() = FakeDeviceInformationPairingWinrt::~FakeDeviceInformationPairingWinrt() =
default; default;
...@@ -51,7 +61,7 @@ HRESULT FakeDeviceInformationPairingWinrt::get_ProtectionLevel( ...@@ -51,7 +61,7 @@ HRESULT FakeDeviceInformationPairingWinrt::get_ProtectionLevel(
HRESULT FakeDeviceInformationPairingWinrt::get_Custom( HRESULT FakeDeviceInformationPairingWinrt::get_Custom(
IDeviceInformationCustomPairing** value) { IDeviceInformationCustomPairing** value) {
return E_NOTIMPL; return custom_.CopyTo(value);
} }
HRESULT HRESULT
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <wrl/client.h> #include <wrl/client.h>
#include <wrl/implements.h> #include <wrl/implements.h>
#include <string>
#include "base/macros.h" #include "base/macros.h"
namespace device { namespace device {
...@@ -21,6 +23,7 @@ class FakeDeviceInformationPairingWinrt ...@@ -21,6 +23,7 @@ class FakeDeviceInformationPairingWinrt
ABI::Windows::Devices::Enumeration::IDeviceInformationPairing2> { ABI::Windows::Devices::Enumeration::IDeviceInformationPairing2> {
public: public:
explicit FakeDeviceInformationPairingWinrt(bool is_paired); explicit FakeDeviceInformationPairingWinrt(bool is_paired);
explicit FakeDeviceInformationPairingWinrt(std::string pin);
~FakeDeviceInformationPairingWinrt() override; ~FakeDeviceInformationPairingWinrt() override;
// IDeviceInformationPairing: // IDeviceInformationPairing:
...@@ -57,8 +60,13 @@ class FakeDeviceInformationPairingWinrt ...@@ -57,8 +60,13 @@ class FakeDeviceInformationPairingWinrt
ABI::Windows::Devices::Enumeration::DeviceUnpairingResult*>** result) ABI::Windows::Devices::Enumeration::DeviceUnpairingResult*>** result)
override; override;
void set_paired(bool is_paired) { is_paired_ = is_paired; }
private: private:
bool is_paired_ = false; bool is_paired_ = false;
Microsoft::WRL::ComPtr<
ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing>
custom_;
DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationPairingWinrt); DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationPairingWinrt);
}; };
......
...@@ -6,13 +6,20 @@ ...@@ -6,13 +6,20 @@
#include <windows.foundation.h> #include <windows.foundation.h>
#include <utility>
#include "base/win/scoped_hstring.h"
namespace device { namespace device {
namespace { namespace {
using ABI::Windows::Devices::Enumeration::IDeviceInformation; using ABI::Windows::Devices::Enumeration::IDeviceInformation;
using ABI::Windows::Devices::Enumeration::DevicePairingKinds; using ABI::Windows::Devices::Enumeration::DevicePairingKinds;
using ABI::Windows::Devices::Enumeration::DevicePairingKinds_ProvidePin;
using ABI::Windows::Foundation::IDeferral; using ABI::Windows::Foundation::IDeferral;
using Microsoft::WRL::Make;
using Microsoft::WRL::ComPtr;
class FakeDeferral class FakeDeferral
: public Microsoft::WRL::RuntimeClass< : public Microsoft::WRL::RuntimeClass<
...@@ -20,20 +27,29 @@ class FakeDeferral ...@@ -20,20 +27,29 @@ class FakeDeferral
Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>, Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
ABI::Windows::Foundation::IDeferral> { ABI::Windows::Foundation::IDeferral> {
public: public:
FakeDeferral() = default; explicit FakeDeferral(
ComPtr<FakeDevicePairingRequestedEventArgsWinrt> pairing_requested)
: pairing_requested_(std::move(pairing_requested)) {}
~FakeDeferral() override = default; ~FakeDeferral() override = default;
// IDeferral: // IDeferral:
IFACEMETHODIMP Complete() override { return E_NOTIMPL; } IFACEMETHODIMP Complete() override {
pairing_requested_->Complete();
return S_OK;
}
private: private:
ComPtr<FakeDevicePairingRequestedEventArgsWinrt> pairing_requested_;
DISALLOW_COPY_AND_ASSIGN(FakeDeferral); DISALLOW_COPY_AND_ASSIGN(FakeDeferral);
}; };
} // namespace } // namespace
FakeDevicePairingRequestedEventArgsWinrt:: FakeDevicePairingRequestedEventArgsWinrt::
FakeDevicePairingRequestedEventArgsWinrt() = default; FakeDevicePairingRequestedEventArgsWinrt(
ComPtr<FakeDeviceInformationCustomPairingWinrt> custom_pairing)
: custom_pairing_(std::move(custom_pairing)) {}
FakeDevicePairingRequestedEventArgsWinrt:: FakeDevicePairingRequestedEventArgsWinrt::
~FakeDevicePairingRequestedEventArgsWinrt() = default; ~FakeDevicePairingRequestedEventArgsWinrt() = default;
...@@ -45,7 +61,8 @@ HRESULT FakeDevicePairingRequestedEventArgsWinrt::get_DeviceInformation( ...@@ -45,7 +61,8 @@ HRESULT FakeDevicePairingRequestedEventArgsWinrt::get_DeviceInformation(
HRESULT FakeDevicePairingRequestedEventArgsWinrt::get_PairingKind( HRESULT FakeDevicePairingRequestedEventArgsWinrt::get_PairingKind(
DevicePairingKinds* value) { DevicePairingKinds* value) {
return E_NOTIMPL; *value = DevicePairingKinds_ProvidePin;
return S_OK;
} }
HRESULT FakeDevicePairingRequestedEventArgsWinrt::get_Pin(HSTRING* value) { HRESULT FakeDevicePairingRequestedEventArgsWinrt::get_Pin(HSTRING* value) {
...@@ -57,12 +74,17 @@ HRESULT FakeDevicePairingRequestedEventArgsWinrt::Accept() { ...@@ -57,12 +74,17 @@ HRESULT FakeDevicePairingRequestedEventArgsWinrt::Accept() {
} }
HRESULT FakeDevicePairingRequestedEventArgsWinrt::AcceptWithPin(HSTRING pin) { HRESULT FakeDevicePairingRequestedEventArgsWinrt::AcceptWithPin(HSTRING pin) {
return E_NOTIMPL; custom_pairing_->AcceptWithPin(base::win::ScopedHString(pin).GetAsUTF8());
return S_OK;
} }
HRESULT FakeDevicePairingRequestedEventArgsWinrt::GetDeferral( HRESULT FakeDevicePairingRequestedEventArgsWinrt::GetDeferral(
IDeferral** result) { IDeferral** result) {
return E_NOTIMPL; return Make<FakeDeferral>(this).CopyTo(result);
}
void FakeDevicePairingRequestedEventArgsWinrt::Complete() {
custom_pairing_->Complete();
} }
} // namespace device } // namespace device
...@@ -6,9 +6,11 @@ ...@@ -6,9 +6,11 @@
#define DEVICE_BLUETOOTH_TEST_FAKE_DEVICE_PAIRING_REQUESTED_EVENT_ARGS_WINRT_H_ #define DEVICE_BLUETOOTH_TEST_FAKE_DEVICE_PAIRING_REQUESTED_EVENT_ARGS_WINRT_H_
#include <windows.devices.enumeration.h> #include <windows.devices.enumeration.h>
#include <wrl/client.h>
#include <wrl/implements.h> #include <wrl/implements.h>
#include "base/macros.h" #include "base/macros.h"
#include "device/bluetooth/test/fake_device_information_custom_pairing_winrt.h"
namespace device { namespace device {
...@@ -19,7 +21,9 @@ class FakeDevicePairingRequestedEventArgsWinrt ...@@ -19,7 +21,9 @@ class FakeDevicePairingRequestedEventArgsWinrt
ABI::Windows::Devices::Enumeration:: ABI::Windows::Devices::Enumeration::
IDevicePairingRequestedEventArgs> { IDevicePairingRequestedEventArgs> {
public: public:
FakeDevicePairingRequestedEventArgsWinrt(); explicit FakeDevicePairingRequestedEventArgsWinrt(
Microsoft::WRL::ComPtr<FakeDeviceInformationCustomPairingWinrt>
custom_pairing);
~FakeDevicePairingRequestedEventArgsWinrt() override; ~FakeDevicePairingRequestedEventArgsWinrt() override;
// IDevicePairingRequestedEventArgs: // IDevicePairingRequestedEventArgs:
...@@ -33,7 +37,12 @@ class FakeDevicePairingRequestedEventArgsWinrt ...@@ -33,7 +37,12 @@ class FakeDevicePairingRequestedEventArgsWinrt
IFACEMETHODIMP GetDeferral( IFACEMETHODIMP GetDeferral(
ABI::Windows::Foundation::IDeferral** result) override; ABI::Windows::Foundation::IDeferral** result) override;
void Complete();
private: private:
Microsoft::WRL::ComPtr<FakeDeviceInformationCustomPairingWinrt>
custom_pairing_;
DISALLOW_COPY_AND_ASSIGN(FakeDevicePairingRequestedEventArgsWinrt); DISALLOW_COPY_AND_ASSIGN(FakeDevicePairingRequestedEventArgsWinrt);
}; };
......
...@@ -13,13 +13,16 @@ using ABI::Windows::Devices::Enumeration::DevicePairingResultStatus; ...@@ -13,13 +13,16 @@ using ABI::Windows::Devices::Enumeration::DevicePairingResultStatus;
namespace device { namespace device {
FakeDevicePairingResultWinrt::FakeDevicePairingResultWinrt() = default; FakeDevicePairingResultWinrt::FakeDevicePairingResultWinrt(
DevicePairingResultStatus status)
: status_(status) {}
FakeDevicePairingResultWinrt::~FakeDevicePairingResultWinrt() = default; FakeDevicePairingResultWinrt::~FakeDevicePairingResultWinrt() = default;
HRESULT FakeDevicePairingResultWinrt::get_Status( HRESULT FakeDevicePairingResultWinrt::get_Status(
DevicePairingResultStatus* status) { DevicePairingResultStatus* status) {
return E_NOTIMPL; *status = status_;
return S_OK;
} }
HRESULT FakeDevicePairingResultWinrt::get_ProtectionLevelUsed( HRESULT FakeDevicePairingResultWinrt::get_ProtectionLevelUsed(
......
...@@ -18,7 +18,8 @@ class FakeDevicePairingResultWinrt ...@@ -18,7 +18,8 @@ class FakeDevicePairingResultWinrt
Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>, Microsoft::WRL::WinRt | Microsoft::WRL::InhibitRoOriginateError>,
ABI::Windows::Devices::Enumeration::IDevicePairingResult> { ABI::Windows::Devices::Enumeration::IDevicePairingResult> {
public: public:
FakeDevicePairingResultWinrt(); explicit FakeDevicePairingResultWinrt(
ABI::Windows::Devices::Enumeration::DevicePairingResultStatus status);
~FakeDevicePairingResultWinrt() override; ~FakeDevicePairingResultWinrt() override;
// IDevicePairingResult: // IDevicePairingResult:
...@@ -30,6 +31,8 @@ class FakeDevicePairingResultWinrt ...@@ -30,6 +31,8 @@ class FakeDevicePairingResultWinrt
override; override;
private: private:
ABI::Windows::Devices::Enumeration::DevicePairingResultStatus status_;
DISALLOW_COPY_AND_ASSIGN(FakeDevicePairingResultWinrt); DISALLOW_COPY_AND_ASSIGN(FakeDevicePairingResultWinrt);
}; };
......
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