[Floss] Implement pairing delegate methods
This adds pairing handling with delegate for these pairing methods: * No delegate/just works (e.g. use case with mouse) * ConfirmPasskey (e.g. use case with an Android phone) * DisplayPasskey (e.g. use case with a keyboard) * RequestPinCode (e.g. use case with an old non-SSP BT device) Bug: b:202334519 Change-Id: I37dcac5062ac9550bd36ad66a8fcb1fa52af86ee Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3272202 Reviewed-by: Abhishek Pandit-Subedi <abhishekpandit@chromium.org> Reviewed-by: Gordon Seto <gordonseto@google.com> Commit-Queue: Sonny Sasaka <sonnysasaka@chromium.org> Cr-Commit-Position: refs/heads/main@{#944775}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
53452be6c9
commit
3ed1c253ce
device/bluetooth
BUILD.gn
floss
@ -440,6 +440,8 @@ component("bluetooth") {
|
||||
"floss/bluetooth_adapter_floss.h",
|
||||
"floss/bluetooth_device_floss.cc",
|
||||
"floss/bluetooth_device_floss.h",
|
||||
"floss/bluetooth_pairing_floss.cc",
|
||||
"floss/bluetooth_pairing_floss.h",
|
||||
"floss/floss_adapter_client.cc",
|
||||
"floss/floss_adapter_client.h",
|
||||
"floss/floss_dbus_client.cc",
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "device/bluetooth/floss/bluetooth_device_floss.h"
|
||||
#include "device/bluetooth/floss/floss_dbus_manager.h"
|
||||
#include "device/bluetooth/floss/floss_features.h"
|
||||
#include "device/bluetooth/public/cpp/bluetooth_address.h"
|
||||
|
||||
namespace floss {
|
||||
|
||||
@ -392,13 +393,15 @@ void BluetoothAdapterFloss::AdapterFoundDevice(
|
||||
auto device_floss =
|
||||
base::WrapUnique(new BluetoothDeviceFloss(this, device_found));
|
||||
|
||||
if (!base::Contains(devices_, device_floss->GetAddress())) {
|
||||
std::string canonical_address =
|
||||
device::CanonicalizeBluetoothAddress(device_floss->GetAddress());
|
||||
if (!base::Contains(devices_, canonical_address)) {
|
||||
// TODO(b/204708206): Populate initial device properties first, e.g.
|
||||
// connection state.
|
||||
|
||||
// Take copy of pointer before moving ownership.
|
||||
BluetoothDeviceFloss* device_ptr = device_floss.get();
|
||||
devices_.emplace(device_floss->GetAddress(), std::move(device_floss));
|
||||
devices_.emplace(canonical_address, std::move(device_floss));
|
||||
|
||||
for (auto& observer : observers_)
|
||||
observer.DeviceAdded(this, device_ptr);
|
||||
@ -414,14 +417,65 @@ void BluetoothAdapterFloss::AdapterSspRequest(
|
||||
uint32_t cod,
|
||||
FlossAdapterClient::BluetoothSspVariant variant,
|
||||
uint32_t passkey) {
|
||||
NOTIMPLEMENTED();
|
||||
BluetoothDeviceFloss* device =
|
||||
static_cast<BluetoothDeviceFloss*>(GetDevice(remote_device.address));
|
||||
|
||||
if (!device) {
|
||||
LOG(WARNING) << "SSP request for an unknown device";
|
||||
return;
|
||||
}
|
||||
|
||||
BluetoothPairingFloss* pairing = device->pairing();
|
||||
|
||||
if (!pairing) {
|
||||
LOG(WARNING) << "SSP request for an unknown pairing";
|
||||
return;
|
||||
}
|
||||
|
||||
device::BluetoothDevice::PairingDelegate* pairing_delegate =
|
||||
pairing->pairing_delegate();
|
||||
|
||||
if (!pairing_delegate) {
|
||||
LOG(WARNING) << "SSP request for an unknown delegate";
|
||||
return;
|
||||
}
|
||||
|
||||
switch (variant) {
|
||||
case FlossAdapterClient::BluetoothSspVariant::kPasskeyConfirmation:
|
||||
pairing->SetPairingExpectation(
|
||||
BluetoothPairingFloss::PairingExpectation::kConfirmation);
|
||||
pairing_delegate->ConfirmPasskey(device, passkey);
|
||||
break;
|
||||
case FlossAdapterClient::BluetoothSspVariant::kPasskeyEntry:
|
||||
// TODO(b/202334519): Test with LEGO Mindstorms EV3.
|
||||
pairing->SetPairingExpectation(
|
||||
BluetoothPairingFloss::PairingExpectation::kPinCode);
|
||||
pairing_delegate->RequestPinCode(device);
|
||||
break;
|
||||
case FlossAdapterClient::BluetoothSspVariant::kConsent:
|
||||
// We don't need to ask pairing delegate for consent, because having a
|
||||
// pairing delegate means that a user is the initiator of this pairing.
|
||||
FlossDBusManager::Get()->GetAdapterClient()->SetPairingConfirmation(
|
||||
base::DoNothing(), remote_device, /*accept=*/true);
|
||||
device->ResetPairing();
|
||||
break;
|
||||
case FlossAdapterClient::BluetoothSspVariant::kPasskeyNotification:
|
||||
pairing_delegate->DisplayPasskey(device, passkey);
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Unimplemented pairing method "
|
||||
<< static_cast<int>(variant);
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothAdapterFloss::DeviceBondStateChanged(
|
||||
const FlossDeviceId& remote_device,
|
||||
uint32_t status,
|
||||
FlossAdapterClient::BondState bond_state) {
|
||||
if (!base::Contains(devices_, remote_device.address)) {
|
||||
std::string canonical_address =
|
||||
device::CanonicalizeBluetoothAddress(remote_device.address);
|
||||
|
||||
if (!base::Contains(devices_, canonical_address)) {
|
||||
LOG(WARNING) << "Received BondStateChanged for a non-existent device";
|
||||
return;
|
||||
}
|
||||
@ -435,9 +489,12 @@ void BluetoothAdapterFloss::DeviceBondStateChanged(
|
||||
<< static_cast<uint32_t>(bond_state);
|
||||
|
||||
BluetoothDeviceFloss* device =
|
||||
static_cast<BluetoothDeviceFloss*>(devices_[remote_device.address].get());
|
||||
static_cast<BluetoothDeviceFloss*>(devices_[canonical_address].get());
|
||||
device->SetBondState(bond_state);
|
||||
NotifyDevicePairedChanged(device, device->IsPaired());
|
||||
NotifyDeviceChanged(device);
|
||||
|
||||
if (bond_state == FlossAdapterClient::BondState::kBonded)
|
||||
device->ConnectAllEnabledProfiles();
|
||||
}
|
||||
|
||||
void BluetoothAdapterFloss::AdapterDeviceConnected(
|
||||
|
@ -40,6 +40,14 @@ void OnCreateBond(BluetoothDeviceFloss::ConnectCallback callback,
|
||||
std::move(callback).Run(connect_error);
|
||||
}
|
||||
|
||||
void OnConnectAllEnabledProfiles(const absl::optional<Void>& ret,
|
||||
const absl::optional<Error>& error) {
|
||||
if (error.has_value()) {
|
||||
BLUETOOTH_LOG(ERROR) << "Failed to connect all enabled profiles: "
|
||||
<< error->name << ": " << error->message;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
using AddressType = device::BluetoothDevice::AddressType;
|
||||
@ -151,21 +159,27 @@ absl::optional<int8_t> BluetoothDeviceFloss::GetInquiryTxPower() const {
|
||||
}
|
||||
|
||||
bool BluetoothDeviceFloss::ExpectingPinCode() const {
|
||||
NOTIMPLEMENTED();
|
||||
if (!pairing_)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
return pairing_->pairing_expectation() ==
|
||||
BluetoothPairingFloss::PairingExpectation::kPinCode;
|
||||
}
|
||||
|
||||
bool BluetoothDeviceFloss::ExpectingPasskey() const {
|
||||
NOTIMPLEMENTED();
|
||||
if (!pairing_)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
return pairing_->pairing_expectation() ==
|
||||
BluetoothPairingFloss::PairingExpectation::kPasskey;
|
||||
}
|
||||
|
||||
bool BluetoothDeviceFloss::ExpectingConfirmation() const {
|
||||
NOTIMPLEMENTED();
|
||||
if (!pairing_)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
return pairing_->pairing_expectation() ==
|
||||
BluetoothPairingFloss::PairingExpectation::kConfirmation;
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::GetConnectionInfo(ConnectionInfoCallback callback) {
|
||||
@ -188,31 +202,37 @@ void BluetoothDeviceFloss::Connect(
|
||||
// No need to pair, or unable to, skip straight to connection.
|
||||
// TODO(b/202334519): Support connection flow without pairing.
|
||||
} else {
|
||||
pairing_ = std::make_unique<BluetoothPairingFloss>(pairing_delegate);
|
||||
FlossDBusManager::Get()->GetAdapterClient()->CreateBond(
|
||||
base::BindOnce(&OnCreateBond, std::move(callback)),
|
||||
FlossDeviceId({address_, name_}),
|
||||
base::BindOnce(&OnCreateBond, std::move(callback)), AsFlossDeviceId(),
|
||||
FlossAdapterClient::BluetoothTransport::kAuto);
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::SetPinCode(const std::string& pincode) {
|
||||
NOTIMPLEMENTED();
|
||||
std::vector<uint8_t> pin(pincode.begin(), pincode.end());
|
||||
FlossDBusManager::Get()->GetAdapterClient()->SetPin(
|
||||
base::DoNothing(), AsFlossDeviceId(), /*accept=*/true, pin);
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::SetPasskey(uint32_t passkey) {
|
||||
// No use case in Chrome OS.
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::ConfirmPairing() {
|
||||
NOTIMPLEMENTED();
|
||||
FlossDBusManager::Get()->GetAdapterClient()->SetPairingConfirmation(
|
||||
base::DoNothing(), AsFlossDeviceId(), /*accept=*/true);
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::RejectPairing() {
|
||||
NOTIMPLEMENTED();
|
||||
FlossDBusManager::Get()->GetAdapterClient()->SetPairingConfirmation(
|
||||
base::DoNothing(), AsFlossDeviceId(), /*accept=*/false);
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::CancelPairing() {
|
||||
NOTIMPLEMENTED();
|
||||
FlossDBusManager::Get()->GetAdapterClient()->CancelBondProcess(
|
||||
base::DoNothing(), AsFlossDeviceId());
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::Disconnect(base::OnceClosure callback,
|
||||
@ -275,6 +295,10 @@ void BluetoothDeviceFloss::AbortWrite(base::OnceClosure callback,
|
||||
}
|
||||
#endif
|
||||
|
||||
FlossDeviceId BluetoothDeviceFloss::AsFlossDeviceId() const {
|
||||
return FlossDeviceId{.address = address_, .name = name_};
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::SetName(const std::string& name) {
|
||||
name_ = name;
|
||||
}
|
||||
@ -288,6 +312,15 @@ void BluetoothDeviceFloss::SetIsConnected(bool is_connected) {
|
||||
is_connected_ = is_connected;
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::ConnectAllEnabledProfiles() {
|
||||
FlossDBusManager::Get()->GetAdapterClient()->ConnectAllEnabledProfiles(
|
||||
base::BindOnce(&OnConnectAllEnabledProfiles), AsFlossDeviceId());
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::ResetPairing() {
|
||||
pairing_.reset();
|
||||
}
|
||||
|
||||
void BluetoothDeviceFloss::CreateGattConnectionImpl(
|
||||
absl::optional<device::BluetoothUUID> service_uuid) {
|
||||
NOTIMPLEMENTED();
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "device/bluetooth/bluetooth_common.h"
|
||||
#include "device/bluetooth/bluetooth_device.h"
|
||||
#include "device/bluetooth/bluetooth_export.h"
|
||||
#include "device/bluetooth/floss/bluetooth_pairing_floss.h"
|
||||
#include "device/bluetooth/floss/floss_adapter_client.h"
|
||||
|
||||
namespace floss {
|
||||
@ -93,9 +94,14 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceFloss
|
||||
AbortWriteErrorCallback error_callback) override;
|
||||
#endif
|
||||
|
||||
FlossDeviceId AsFlossDeviceId() const;
|
||||
void SetName(const std::string& name);
|
||||
void SetBondState(FlossAdapterClient::BondState bond_state);
|
||||
void SetIsConnected(bool is_connected);
|
||||
void ConnectAllEnabledProfiles();
|
||||
void ResetPairing();
|
||||
|
||||
BluetoothPairingFloss* pairing() const { return pairing_.get(); }
|
||||
|
||||
protected:
|
||||
// BluetoothDevice override
|
||||
@ -141,6 +147,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceFloss
|
||||
// not used in the Chrome layer.
|
||||
bool is_connected_ = false;
|
||||
|
||||
// Represents currently ongoing pairing with this remote device.
|
||||
std::unique_ptr<BluetoothPairingFloss> pairing_;
|
||||
|
||||
base::WeakPtrFactory<BluetoothDeviceFloss> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
|
@ -24,6 +24,7 @@ using ::device::BluetoothDevice;
|
||||
using ::device::BluetoothDiscoverySession;
|
||||
using ::device::MockPairingDelegate;
|
||||
using ::device::TestBluetoothAdapterObserver;
|
||||
using ::testing::_;
|
||||
using ::testing::StrictMock;
|
||||
|
||||
} // namespace
|
||||
@ -131,6 +132,93 @@ TEST_F(BluetoothFlossTest, PairJustWorks) {
|
||||
EXPECT_TRUE(device->IsPaired());
|
||||
}
|
||||
|
||||
TEST_F(BluetoothFlossTest, PairConfirmPasskey) {
|
||||
InitializeAdapter();
|
||||
DiscoverDevices();
|
||||
|
||||
BluetoothDevice* device =
|
||||
adapter_->GetDevice(FakeFlossAdapterClient::kPhoneAddress);
|
||||
ASSERT_TRUE(device != nullptr);
|
||||
ASSERT_FALSE(device->IsPaired());
|
||||
|
||||
StrictMock<MockPairingDelegate> pairing_delegate;
|
||||
EXPECT_CALL(pairing_delegate,
|
||||
ConfirmPasskey(_, FakeFlossAdapterClient::kPasskey))
|
||||
.WillOnce([](BluetoothDevice* device, uint32_t passkey) {
|
||||
device->ConfirmPairing();
|
||||
});
|
||||
base::RunLoop run_loop;
|
||||
device->Connect(
|
||||
&pairing_delegate,
|
||||
base::BindLambdaForTesting(
|
||||
[&run_loop](absl::optional<BluetoothDevice::ConnectErrorCode> error) {
|
||||
EXPECT_FALSE(error.has_value());
|
||||
run_loop.Quit();
|
||||
}));
|
||||
run_loop.Run();
|
||||
|
||||
EXPECT_TRUE(device->IsPaired());
|
||||
}
|
||||
|
||||
TEST_F(BluetoothFlossTest, PairDisplayPasskey) {
|
||||
InitializeAdapter();
|
||||
DiscoverDevices();
|
||||
|
||||
BluetoothDevice* device =
|
||||
adapter_->GetDevice(FakeFlossAdapterClient::kKeyboardAddress);
|
||||
ASSERT_TRUE(device != nullptr);
|
||||
ASSERT_FALSE(device->IsPaired());
|
||||
|
||||
StrictMock<MockPairingDelegate> pairing_delegate;
|
||||
EXPECT_CALL(pairing_delegate,
|
||||
DisplayPasskey(_, FakeFlossAdapterClient::kPasskey))
|
||||
.WillOnce([this](BluetoothDevice* device, uint32_t passkey) {
|
||||
// Pretend that the remote device has completed passkey entry.
|
||||
fake_floss_adapter_client_->NotifyObservers(base::BindLambdaForTesting(
|
||||
[device](FlossAdapterClient::Observer* observer) {
|
||||
observer->DeviceBondStateChanged(
|
||||
FlossDeviceId({.address = device->GetAddress(), .name = ""}),
|
||||
/*status=*/0, FlossAdapterClient::BondState::kBonded);
|
||||
}));
|
||||
});
|
||||
base::RunLoop run_loop;
|
||||
device->Connect(
|
||||
&pairing_delegate,
|
||||
base::BindLambdaForTesting(
|
||||
[&run_loop](absl::optional<BluetoothDevice::ConnectErrorCode> error) {
|
||||
EXPECT_FALSE(error.has_value());
|
||||
run_loop.Quit();
|
||||
}));
|
||||
run_loop.Run();
|
||||
|
||||
EXPECT_TRUE(device->IsPaired());
|
||||
}
|
||||
|
||||
TEST_F(BluetoothFlossTest, PairPasskeyEntry) {
|
||||
InitializeAdapter();
|
||||
DiscoverDevices();
|
||||
|
||||
BluetoothDevice* device =
|
||||
adapter_->GetDevice(FakeFlossAdapterClient::kOldDeviceAddress);
|
||||
ASSERT_TRUE(device != nullptr);
|
||||
ASSERT_FALSE(device->IsPaired());
|
||||
|
||||
StrictMock<MockPairingDelegate> pairing_delegate;
|
||||
EXPECT_CALL(pairing_delegate, RequestPinCode(_))
|
||||
.WillOnce([](BluetoothDevice* device) { device->SetPinCode("pin123"); });
|
||||
base::RunLoop run_loop;
|
||||
device->Connect(
|
||||
&pairing_delegate,
|
||||
base::BindLambdaForTesting(
|
||||
[&run_loop](absl::optional<BluetoothDevice::ConnectErrorCode> error) {
|
||||
EXPECT_FALSE(error.has_value());
|
||||
run_loop.Quit();
|
||||
}));
|
||||
run_loop.Run();
|
||||
|
||||
EXPECT_TRUE(device->IsPaired());
|
||||
}
|
||||
|
||||
TEST_F(BluetoothFlossTest, UpdatesDeviceConnectionState) {
|
||||
InitializeAdapter();
|
||||
DiscoverDevices();
|
||||
|
21
device/bluetooth/floss/bluetooth_pairing_floss.cc
Normal file
21
device/bluetooth/floss/bluetooth_pairing_floss.cc
Normal file
@ -0,0 +1,21 @@
|
||||
// Copyright 2021 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/floss/bluetooth_pairing_floss.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "device/bluetooth/bluetooth_device.h"
|
||||
#include "device/bluetooth/floss/bluetooth_device_floss.h"
|
||||
|
||||
using device::BluetoothDevice;
|
||||
|
||||
namespace floss {
|
||||
|
||||
BluetoothPairingFloss::BluetoothPairingFloss(
|
||||
BluetoothDevice::PairingDelegate* pairing_delegate)
|
||||
: pairing_delegate_(pairing_delegate) {}
|
||||
|
||||
BluetoothPairingFloss::~BluetoothPairingFloss() = default;
|
||||
|
||||
} // namespace floss
|
60
device/bluetooth/floss/bluetooth_pairing_floss.h
Normal file
60
device/bluetooth/floss/bluetooth_pairing_floss.h
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2021 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_FLOSS_BLUETOOTH_PAIRING_FLOSS_H_
|
||||
#define DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_PAIRING_FLOSS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "device/bluetooth/bluetooth_device.h"
|
||||
#include "device/bluetooth/dbus/bluetooth_agent_service_provider.h"
|
||||
|
||||
namespace floss {
|
||||
|
||||
// The BluetoothPairingFloss class represents an ongoing pairing process with a
|
||||
// remote device.
|
||||
class BluetoothPairingFloss {
|
||||
public:
|
||||
enum PairingExpectation {
|
||||
kNone,
|
||||
kPinCode,
|
||||
kPasskey,
|
||||
kConfirmation,
|
||||
};
|
||||
|
||||
explicit BluetoothPairingFloss(
|
||||
device::BluetoothDevice::PairingDelegate* pairing_delegate);
|
||||
|
||||
BluetoothPairingFloss(const BluetoothPairingFloss&) = delete;
|
||||
BluetoothPairingFloss& operator=(const BluetoothPairingFloss&) = delete;
|
||||
|
||||
~BluetoothPairingFloss();
|
||||
|
||||
// Returns the pairing delegate being used by this pairing object.
|
||||
device::BluetoothDevice::PairingDelegate* pairing_delegate() const {
|
||||
return pairing_delegate_;
|
||||
}
|
||||
|
||||
// Returns the type of the expected response from the local user.
|
||||
PairingExpectation pairing_expectation() const {
|
||||
return pairing_expectation_;
|
||||
}
|
||||
|
||||
// Sets the type of the expected response from the local user.
|
||||
void SetPairingExpectation(PairingExpectation expectation) {
|
||||
pairing_expectation_ = expectation;
|
||||
}
|
||||
|
||||
private:
|
||||
// UI Pairing Delegate to make method calls on, this must live as long as
|
||||
// the object capturing the PairingContext.
|
||||
device::BluetoothDevice::PairingDelegate* pairing_delegate_;
|
||||
|
||||
// If pending user interaction, what is expected from the user.
|
||||
PairingExpectation pairing_expectation_ = PairingExpectation::kNone;
|
||||
};
|
||||
|
||||
} // namespace floss
|
||||
|
||||
#endif // DEVICE_BLUETOOTH_FLOSS_BLUETOOTH_PAIRING_FLOSS_H_
|
@ -20,6 +20,10 @@ FakeFlossAdapterClient::FakeFlossAdapterClient() = default;
|
||||
FakeFlossAdapterClient::~FakeFlossAdapterClient() = default;
|
||||
|
||||
const char FakeFlossAdapterClient::kJustWorksAddress[] = "11:22:33:44:55:66";
|
||||
const char FakeFlossAdapterClient::kKeyboardAddress[] = "aa:aa:aa:aa:aa:aa";
|
||||
const char FakeFlossAdapterClient::kPhoneAddress[] = "bb:bb:bb:bb:bb:bb";
|
||||
const char FakeFlossAdapterClient::kOldDeviceAddress[] = "cc:cc:cc:cc:cc:cc";
|
||||
const uint32_t FakeFlossAdapterClient::kPasskey = 123456;
|
||||
|
||||
void FakeFlossAdapterClient::Init(dbus::Bus* bus,
|
||||
const std::string& service_name,
|
||||
@ -30,6 +34,9 @@ void FakeFlossAdapterClient::StartDiscovery(ResponseCallback<Void> callback) {
|
||||
|
||||
for (auto& observer : observers_) {
|
||||
observer.AdapterFoundDevice(FlossDeviceId({kJustWorksAddress, ""}));
|
||||
observer.AdapterFoundDevice(FlossDeviceId({kKeyboardAddress, ""}));
|
||||
observer.AdapterFoundDevice(FlossDeviceId({kPhoneAddress, ""}));
|
||||
observer.AdapterFoundDevice(FlossDeviceId({kOldDeviceAddress, ""}));
|
||||
}
|
||||
|
||||
PostDelayedTask(base::BindOnce(std::move(callback), /*ret=*/absl::nullopt,
|
||||
@ -47,13 +54,51 @@ void FakeFlossAdapterClient::CreateBond(ResponseCallback<Void> callback,
|
||||
BluetoothTransport transport) {
|
||||
// TODO(b/202874707): Simulate pairing failures.
|
||||
|
||||
for (auto& observer : observers_) {
|
||||
observer.DeviceBondStateChanged(device, /*status=*/0,
|
||||
FlossAdapterClient::BondState::kBonded);
|
||||
}
|
||||
if (device.address == kJustWorksAddress) {
|
||||
for (auto& observer : observers_) {
|
||||
observer.DeviceBondStateChanged(device, /*status=*/0,
|
||||
FlossAdapterClient::BondState::kBonded);
|
||||
}
|
||||
|
||||
PostDelayedTask(base::BindOnce(std::move(callback), /*ret=*/absl::nullopt,
|
||||
/*err=*/absl::nullopt));
|
||||
PostDelayedTask(base::BindOnce(std::move(callback), /*ret=*/absl::nullopt,
|
||||
/*err=*/absl::nullopt));
|
||||
} else if (device.address == kKeyboardAddress) {
|
||||
for (auto& observer : observers_) {
|
||||
observer.AdapterSspRequest(device, /*cod=*/0,
|
||||
BluetoothSspVariant::kPasskeyNotification,
|
||||
kPasskey);
|
||||
}
|
||||
|
||||
PostDelayedTask(base::BindOnce(std::move(callback), /*ret=*/absl::nullopt,
|
||||
/*err=*/absl::nullopt));
|
||||
} else if (device.address == kPhoneAddress) {
|
||||
for (auto& observer : observers_) {
|
||||
observer.AdapterSspRequest(device, /*cod=*/0,
|
||||
BluetoothSspVariant::kPasskeyConfirmation,
|
||||
kPasskey);
|
||||
}
|
||||
|
||||
PostDelayedTask(base::BindOnce(std::move(callback), /*ret=*/absl::nullopt,
|
||||
/*err=*/absl::nullopt));
|
||||
} else if (device.address == kOldDeviceAddress) {
|
||||
for (auto& observer : observers_) {
|
||||
observer.AdapterSspRequest(device, /*cod=*/0,
|
||||
BluetoothSspVariant::kPasskeyEntry, 0);
|
||||
}
|
||||
|
||||
PostDelayedTask(base::BindOnce(std::move(callback), /*ret=*/absl::nullopt,
|
||||
/*err=*/absl::nullopt));
|
||||
} else {
|
||||
PostDelayedTask(base::BindOnce(
|
||||
std::move(callback), /*ret=*/absl::nullopt,
|
||||
floss::Error("org.chromium.bluetooth.UnknownDevice", /*message=*/"")));
|
||||
}
|
||||
}
|
||||
|
||||
void FakeFlossAdapterClient::ConnectAllEnabledProfiles(
|
||||
ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void FakeFlossAdapterClient::PostDelayedTask(base::OnceClosure callback) {
|
||||
@ -68,4 +113,30 @@ void FakeFlossAdapterClient::NotifyObservers(
|
||||
}
|
||||
}
|
||||
|
||||
void FakeFlossAdapterClient::SetPairingConfirmation(
|
||||
ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device,
|
||||
bool accept) {
|
||||
for (auto& observer : observers_) {
|
||||
observer.DeviceBondStateChanged(device, /*status=*/0,
|
||||
FlossAdapterClient::BondState::kBonded);
|
||||
}
|
||||
|
||||
PostDelayedTask(base::BindOnce(std::move(callback), /*ret=*/absl::nullopt,
|
||||
/*err=*/absl::nullopt));
|
||||
}
|
||||
|
||||
void FakeFlossAdapterClient::SetPin(ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device,
|
||||
bool accept,
|
||||
const std::vector<uint8_t>& pin) {
|
||||
for (auto& observer : observers_) {
|
||||
observer.DeviceBondStateChanged(device, /*status=*/0,
|
||||
FlossAdapterClient::BondState::kBonded);
|
||||
}
|
||||
|
||||
PostDelayedTask(base::BindOnce(std::move(callback), /*ret=*/absl::nullopt,
|
||||
/*err=*/absl::nullopt));
|
||||
}
|
||||
|
||||
} // namespace floss
|
||||
|
@ -20,6 +20,10 @@ class DEVICE_BLUETOOTH_EXPORT FakeFlossAdapterClient
|
||||
// The address of a device without Keyboard nor Display IO capability,
|
||||
// triggering Just Works pairing when used in tests.
|
||||
static const char kJustWorksAddress[];
|
||||
static const char kKeyboardAddress[];
|
||||
static const char kPhoneAddress[];
|
||||
static const char kOldDeviceAddress[];
|
||||
static const uint32_t kPasskey;
|
||||
|
||||
// Fake overrides.
|
||||
void Init(dbus::Bus* bus,
|
||||
@ -30,6 +34,15 @@ class DEVICE_BLUETOOTH_EXPORT FakeFlossAdapterClient
|
||||
void CreateBond(ResponseCallback<Void> callback,
|
||||
FlossDeviceId device,
|
||||
BluetoothTransport transport) override;
|
||||
void ConnectAllEnabledProfiles(ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device) override;
|
||||
void SetPairingConfirmation(ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device,
|
||||
bool accept) override;
|
||||
void SetPin(ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device,
|
||||
bool accept,
|
||||
const std::vector<uint8_t>& pin) override;
|
||||
|
||||
// Helper for posting a delayed task.
|
||||
void PostDelayedTask(base::OnceClosure callback);
|
||||
|
@ -53,6 +53,12 @@ void FlossAdapterClient::CreateBond(ResponseCallback<Void> callback,
|
||||
transport);
|
||||
}
|
||||
|
||||
void FlossAdapterClient::CancelBondProcess(ResponseCallback<Void> callback,
|
||||
FlossDeviceId device) {
|
||||
CallAdapterMethod1<Void>(std::move(callback), adapter::kCancelBondProcess,
|
||||
device);
|
||||
}
|
||||
|
||||
void FlossAdapterClient::GetConnectionState(ResponseCallback<uint32_t> callback,
|
||||
const FlossDeviceId& device) {
|
||||
CallAdapterMethod1<uint32_t>(std::move(callback),
|
||||
@ -73,6 +79,14 @@ void FlossAdapterClient::SetPairingConfirmation(ResponseCallback<Void> callback,
|
||||
adapter::kSetPairingConfirmation, device, accept);
|
||||
}
|
||||
|
||||
void FlossAdapterClient::SetPin(ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device,
|
||||
bool accept,
|
||||
const std::vector<uint8_t>& pin) {
|
||||
CallAdapterMethod3<Void>(std::move(callback), adapter::kSetPin, device,
|
||||
accept, pin);
|
||||
}
|
||||
|
||||
void FlossAdapterClient::SetPasskey(ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device,
|
||||
bool accept,
|
||||
|
@ -129,6 +129,10 @@ class DEVICE_BLUETOOTH_EXPORT FlossAdapterClient : public FlossDBusClient {
|
||||
FlossDeviceId device,
|
||||
BluetoothTransport transport);
|
||||
|
||||
// Cancel a bond process.
|
||||
virtual void CancelBondProcess(ResponseCallback<Void> callback,
|
||||
FlossDeviceId device);
|
||||
|
||||
// Get connection state of a device.
|
||||
// TODO(b/202334519): Change return type to enum instead of u32
|
||||
virtual void GetConnectionState(ResponseCallback<uint32_t> callback,
|
||||
@ -144,6 +148,12 @@ class DEVICE_BLUETOOTH_EXPORT FlossAdapterClient : public FlossDBusClient {
|
||||
const FlossDeviceId& device,
|
||||
bool accept);
|
||||
|
||||
// Indicates whether the user approves the pairing with the given pin.
|
||||
virtual void SetPin(ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device,
|
||||
bool accept,
|
||||
const std::vector<uint8_t>& pin);
|
||||
|
||||
// Indicates whether the user approves the pairing with the given passkey.
|
||||
virtual void SetPasskey(ResponseCallback<Void> callback,
|
||||
const FlossDeviceId& device,
|
||||
|
@ -44,11 +44,13 @@ const char kGetAddress[] = "GetAddress";
|
||||
const char kStartDiscovery[] = "StartDiscovery";
|
||||
const char kCancelDiscovery[] = "CancelDiscovery";
|
||||
const char kCreateBond[] = "CreateBond";
|
||||
const char kCancelBondProcess[] = "CancelBondProcess";
|
||||
const char kGetConnectionState[] = "GetConnectionState";
|
||||
const char kConnectAllEnabledProfiles[] = "ConnectAllEnabledProfiles";
|
||||
const char kRegisterCallback[] = "RegisterCallback";
|
||||
const char kRegisterConnectionCallback[] = "RegisterConnectionCallback";
|
||||
const char kSetPairingConfirmation[] = "SetPairingConfirmation";
|
||||
const char kSetPin[] = "SetPin";
|
||||
const char kSetPasskey[] = "SetPasskey";
|
||||
|
||||
// TODO(abps) - Rename this to AdapterCallback in platform and here
|
||||
|
@ -32,6 +32,7 @@ extern DEVICE_BLUETOOTH_EXPORT const char kGetAddress[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kStartDiscovery[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kCancelDiscovery[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kCreateBond[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kCancelBondProcess[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kGetConnectionState[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kConnectAllEnabledProfiles[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kRegisterCallback[];
|
||||
@ -39,6 +40,7 @@ extern DEVICE_BLUETOOTH_EXPORT const char kRegisterConnectionCallback[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kCallbackInterface[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kConnectionCallbackInterface[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kSetPairingConfirmation[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kSetPin[];
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kSetPasskey[];
|
||||
|
||||
extern DEVICE_BLUETOOTH_EXPORT const char kOnAddressChanged[];
|
||||
|
Reference in New Issue
Block a user