diff --git a/ash/components/hid_detection/bluetooth_hid_detector.h b/ash/components/hid_detection/bluetooth_hid_detector.h index 8ebd0d20e5d5ee..7a2368c1662f0e 100644 --- a/ash/components/hid_detection/bluetooth_hid_detector.h +++ b/ash/components/hid_detection/bluetooth_hid_detector.h @@ -13,9 +13,15 @@ namespace hid_detection { // currently paired with. class BluetoothHidDetector { public: + struct InputDevicesStatus { + bool pointer_is_missing; + bool keyboard_is_missing; + }; + virtual ~BluetoothHidDetector(); - virtual void StartBluetoothHidDetection() = 0; + virtual void StartBluetoothHidDetection( + InputDevicesStatus input_devices_status) = 0; virtual void StopBluetoothHidDetection() = 0; protected: diff --git a/ash/components/hid_detection/bluetooth_hid_detector_impl.cc b/ash/components/hid_detection/bluetooth_hid_detector_impl.cc index 0ed65397ca5d37..281e1d2494dedc 100644 --- a/ash/components/hid_detection/bluetooth_hid_detector_impl.cc +++ b/ash/components/hid_detection/bluetooth_hid_detector_impl.cc @@ -6,10 +6,14 @@ #include "ash/public/cpp/bluetooth_config_service.h" #include "components/device_event_log/device_event_log.h" -using chromeos::bluetooth_config::mojom::BluetoothSystemState; - namespace ash { namespace hid_detection { +namespace { +using chromeos::bluetooth_config::mojom::BluetoothDevicePropertiesPtr; +using chromeos::bluetooth_config::mojom::BluetoothSystemState; +using chromeos::bluetooth_config::mojom::DeviceType; +using chromeos::bluetooth_config::mojom::KeyEnteredHandler; +} // namespace BluetoothHidDetectorImpl::BluetoothHidDetectorImpl() = default; @@ -18,9 +22,15 @@ BluetoothHidDetectorImpl::~BluetoothHidDetectorImpl() { << "BluetoothHidDetectorImpl is destroyed."; } -void BluetoothHidDetectorImpl::StartBluetoothHidDetection() { +void BluetoothHidDetectorImpl::StartBluetoothHidDetection( + InputDevicesStatus input_devices_status) { + DCHECK(input_devices_status.pointer_is_missing || + input_devices_status.keyboard_is_missing) + << "StartBluetoothHidDetection() called when neither pointer or keyboard " + << "is missing"; DCHECK_EQ(kNotStarted, state_); HID_LOG(EVENT) << "Starting Bluetooth HID detection"; + input_devices_status_ = input_devices_status; state_ = kStarting; GetBluetoothConfigService( cros_bluetooth_config_remote_.BindNewPipeAndPassReceiver()); @@ -36,7 +46,7 @@ void BluetoothHidDetectorImpl::StopBluetoothHidDetection() { cros_bluetooth_config_remote_->SetBluetoothHidDetectionActive(false); cros_bluetooth_config_remote_.reset(); system_properties_observer_receiver_.reset(); - bluetooth_discovery_delegate_receiver_.reset(); + ResetDiscoveryState(); } void BluetoothHidDetectorImpl::OnPropertiesUpdated( @@ -80,7 +90,6 @@ void BluetoothHidDetectorImpl::OnPropertiesUpdated( HID_LOG(EVENT) << "Bluetooth adapter has stopped being enabled while " << "Bluetooth HID detection is in progress"; state_ = kStoppedExternally; - bluetooth_discovery_delegate_receiver_.reset(); } return; case kStoppedExternally: @@ -98,15 +107,132 @@ void BluetoothHidDetectorImpl::OnPropertiesUpdated( void BluetoothHidDetectorImpl::OnBluetoothDiscoveryStarted( mojo::PendingRemote handler) { - // TODO(crbug.com/1299099): Implement pairing. + HID_LOG(EVENT) << "Bluetooth discovery started."; + DCHECK(!device_pairing_handler_remote_); + device_pairing_handler_remote_.Bind(std::move(handler)); } -void BluetoothHidDetectorImpl::OnBluetoothDiscoveryStopped() {} +void BluetoothHidDetectorImpl::OnBluetoothDiscoveryStopped() { + HID_LOG(EVENT) << "Bluetooth discovery stopped."; + ResetDiscoveryState(); +} void BluetoothHidDetectorImpl::OnDiscoveredDevicesListChanged( - std::vector - discovered_devices) { - // TODO(crbug.com/1299099): Implement pairing. + std::vector discovered_devices) { + for (const auto& discovered_device : discovered_devices) { + if (!ShouldAttemptToPairWithDevice(discovered_device)) + continue; + if (queued_device_ids_.contains(discovered_device->id)) + continue; + + queued_device_ids_.insert(discovered_device->id); + queue_->emplace(discovered_device.Clone()); + HID_LOG(EVENT) << "Queuing device: " << discovered_device->id << ". [" + << queue_->size() << "] devices now in queue."; + } + ProcessQueue(); +} + +void BluetoothHidDetectorImpl::RequestPinCode(RequestPinCodeCallback callback) { + // TODO(crbug/1299099): Implement. +} + +void BluetoothHidDetectorImpl::RequestPasskey(RequestPasskeyCallback callback) { + // TODO(crbug/1299099): Implement. +} + +void BluetoothHidDetectorImpl::DisplayPinCode( + const std::string& pin_code, + mojo::PendingReceiver handler) { + // TODO(crbug/1299099): Implement. +} + +void BluetoothHidDetectorImpl::DisplayPasskey( + const std::string& passkey, + mojo::PendingReceiver handler) { + // TODO(crbug/1299099): Implement. +} + +void BluetoothHidDetectorImpl::ConfirmPasskey(const std::string& passkey, + ConfirmPasskeyCallback callback) { + // TODO(crbug/1299099): Implement. +} + +void BluetoothHidDetectorImpl::AuthorizePairing( + AuthorizePairingCallback callback) { + // TODO(crbug/1299099): Implement. +} + +bool BluetoothHidDetectorImpl::ShouldAttemptToPairWithDevice( + const BluetoothDevicePropertiesPtr& device) { + switch (device->device_type) { + case DeviceType::kMouse: + [[fallthrough]]; + case DeviceType::kTablet: + return input_devices_status_.pointer_is_missing; + case DeviceType::kKeyboard: + return input_devices_status_.keyboard_is_missing; + case DeviceType::kKeyboardMouseCombo: + return input_devices_status_.pointer_is_missing || + input_devices_status_.keyboard_is_missing; + default: + return false; + } +} + +void BluetoothHidDetectorImpl::ProcessQueue() { + if (current_pairing_device_) + return; + + if (queue_->empty()) { + HID_LOG(DEBUG) << "No devices queued"; + return; + } + + current_pairing_device_ = std::move(queue_->front()); + queue_->pop(); + HID_LOG(EVENT) << "Popped device with id: " + << current_pairing_device_.value()->id + << " from front of queue. [" << queue_->size() + << "] devices now in queue."; + + // TODO(crbug.com/1299099): Check if device type is still missing and return + // early if not. + + // TODO(crbug.com/1299099): Notify delegate of change in status. + HID_LOG(EVENT) << "Pairing with device with id: " + << current_pairing_device_.value()->id; + device_pairing_handler_remote_->PairDevice( + current_pairing_device_.value()->id, + device_pairing_delegate_receiver_.BindNewPipeAndPassRemote(), + base::BindOnce(&BluetoothHidDetectorImpl::OnPairDevice, + weak_ptr_factory_.GetWeakPtr())); +} + +void BluetoothHidDetectorImpl::OnPairDevice( + chromeos::bluetooth_config::mojom::PairingResult pairing_result) { + // TODO(crbug.com/1299099): Notify delegate of change in status. + HID_LOG(EVENT) << "Finished pairing with " + << current_pairing_device_.value()->id + << ", result: " << pairing_result << ", [" << queue_->size() + << "] devices still in queue."; + queued_device_ids_.erase(current_pairing_device_.value()->id); + current_pairing_device_.reset(); + device_pairing_delegate_receiver_.reset(); + ProcessQueue(); +} + +void BluetoothHidDetectorImpl::ResetDiscoveryState() { + // Reset Mojo-related properties. + bluetooth_discovery_delegate_receiver_.reset(); + device_pairing_handler_remote_.reset(); + device_pairing_delegate_receiver_.reset(); + + // Reset queue-related properties. + current_pairing_device_.reset(); + queue_ = std::make_unique>(); + queued_device_ids_.clear(); } } // namespace hid_detection diff --git a/ash/components/hid_detection/bluetooth_hid_detector_impl.h b/ash/components/hid_detection/bluetooth_hid_detector_impl.h index df359ddfdbcd89..50b1fd8818fe50 100644 --- a/ash/components/hid_detection/bluetooth_hid_detector_impl.h +++ b/ash/components/hid_detection/bluetooth_hid_detector_impl.h @@ -6,6 +6,9 @@ #define ASH_COMPONENTS_HID_DETECTION_BLUETOOTH_HID_DETECTOR_IMPL_H_ #include "ash/components/hid_detection/bluetooth_hid_detector.h" +#include "base/containers/flat_set.h" +#include "base/containers/queue.h" +#include "base/memory/weak_ptr.h" #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h" #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" @@ -17,13 +20,15 @@ namespace hid_detection { class BluetoothHidDetectorImpl : public BluetoothHidDetector, public chromeos::bluetooth_config::mojom::SystemPropertiesObserver, - public chromeos::bluetooth_config::mojom::BluetoothDiscoveryDelegate { + public chromeos::bluetooth_config::mojom::BluetoothDiscoveryDelegate, + public chromeos::bluetooth_config::mojom::DevicePairingDelegate { public: BluetoothHidDetectorImpl(); ~BluetoothHidDetectorImpl() override; // BluetoothHidDetector: - void StartBluetoothHidDetection() override; + void StartBluetoothHidDetection( + InputDevicesStatus input_devices_status) override; void StopBluetoothHidDetection() override; private: @@ -63,6 +68,47 @@ class BluetoothHidDetectorImpl chromeos::bluetooth_config::mojom::BluetoothDevicePropertiesPtr> discovered_devices) override; + // mojom::DevicePairingDelegate: + void RequestPinCode(RequestPinCodeCallback callback) override; + void RequestPasskey(RequestPasskeyCallback callback) override; + void DisplayPinCode(const std::string& pin_code, + mojo::PendingReceiver< + chromeos::bluetooth_config::mojom::KeyEnteredHandler> + handler) override; + void DisplayPasskey(const std::string& passkey, + mojo::PendingReceiver< + chromeos::bluetooth_config::mojom::KeyEnteredHandler> + handler) override; + void ConfirmPasskey(const std::string& passkey, + ConfirmPasskeyCallback callback) override; + void AuthorizePairing(AuthorizePairingCallback callback) override; + + bool ShouldAttemptToPairWithDevice( + const chromeos::bluetooth_config::mojom::BluetoothDevicePropertiesPtr& + device); + + void ProcessQueue(); + void OnPairDevice( + chromeos::bluetooth_config::mojom::PairingResult pairing_result); + + // Resets properties related to discovery, pairing handlers and queueing. + void ResetDiscoveryState(); + + // Map that contains the ids of the devices in |queue_|. + base::flat_set queued_device_ids_; + + // The queue of devices that will be attempted to be paired with. + std::unique_ptr> + queue_ = std::make_unique>(); + + // The device currently being paired with. + absl::optional< + chromeos::bluetooth_config::mojom::BluetoothDevicePropertiesPtr> + current_pairing_device_; + + InputDevicesStatus input_devices_status_; State state_ = kNotStarted; mojo::Remote @@ -71,6 +117,12 @@ class BluetoothHidDetectorImpl system_properties_observer_receiver_{this}; mojo::Receiver bluetooth_discovery_delegate_receiver_{this}; + mojo::Remote + device_pairing_handler_remote_; + mojo::Receiver + device_pairing_delegate_receiver_{this}; + + base::WeakPtrFactory weak_ptr_factory_{this}; }; } // namespace hid_detection diff --git a/ash/components/hid_detection/bluetooth_hid_detector_impl_unittest.cc b/ash/components/hid_detection/bluetooth_hid_detector_impl_unittest.cc index f3947c85e203d3..2cd9feede93f4a 100644 --- a/ash/components/hid_detection/bluetooth_hid_detector_impl_unittest.cc +++ b/ash/components/hid_detection/bluetooth_hid_detector_impl_unittest.cc @@ -8,13 +8,18 @@ #include "chromeos/services/bluetooth_config/fake_adapter_state_controller.h" #include "chromeos/services/bluetooth_config/fake_bluetooth_power_controller.h" #include "chromeos/services/bluetooth_config/fake_device_cache.h" +#include "chromeos/services/bluetooth_config/fake_device_pairing_handler.h" +#include "chromeos/services/bluetooth_config/fake_discovered_devices_provider.h" #include "chromeos/services/bluetooth_config/fake_discovery_session_manager.h" #include "chromeos/services/bluetooth_config/public/mojom/cros_bluetooth_config.mojom.h" #include "chromeos/services/bluetooth_config/scoped_bluetooth_config_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" +using chromeos::bluetooth_config::FakeDevicePairingHandler; using chromeos::bluetooth_config::mojom::BluetoothDeviceProperties; +using chromeos::bluetooth_config::mojom::BluetoothDevicePropertiesPtr; using chromeos::bluetooth_config::mojom::BluetoothSystemState; +using chromeos::bluetooth_config::mojom::DeviceType; using chromeos::bluetooth_config::mojom::PairedBluetoothDeviceProperties; using chromeos::bluetooth_config::mojom::PairedBluetoothDevicePropertiesPtr; @@ -39,8 +44,11 @@ class BluetoothHidDetectorImplTest : public testing::Test { StopBluetoothHidDetection(); } - void StartBluetoothHidDetection() { - bluetooth_hid_detector_.StartBluetoothHidDetection(); + void StartBluetoothHidDetection(bool pointer_is_missing = true, + bool keyboard_is_missing = true) { + bluetooth_hid_detector_.StartBluetoothHidDetection( + {.pointer_is_missing = pointer_is_missing, + .keyboard_is_missing = keyboard_is_missing}); base::RunLoop().RunUntilIdle(); } @@ -87,9 +95,53 @@ class BluetoothHidDetectorImplTest : public testing::Test { base::RunLoop().RunUntilIdle(); } + void AddUnpairedDevice(std::string* id_out, DeviceType device_type) { + // We use the number of devices created in this test as the id. + *id_out = base::NumberToString(num_devices_created_); + ++num_devices_created_; + + auto device = BluetoothDeviceProperties::New(); + device->id = *id_out; + device->device_type = device_type; + unpaired_devices_.push_back(device.Clone()); + + UpdateDiscoveredDevicesProviderDevices(); + base::RunLoop().RunUntilIdle(); + } + + void RemoveUnpairedDevice(const std::string& device_id) { + unpaired_devices_.erase( + std::remove_if(unpaired_devices_.begin(), unpaired_devices_.end(), + [device_id](BluetoothDevicePropertiesPtr const& device) { + return device->id == device_id; + }), + unpaired_devices_.end()); + + UpdateDiscoveredDevicesProviderDevices(); + base::RunLoop().RunUntilIdle(); + } + + std::vector GetDevicePairingHandlers() { + return scoped_bluetooth_config_test_helper_ + .fake_discovery_session_manager() + ->device_pairing_handlers(); + } + private: + void UpdateDiscoveredDevicesProviderDevices() { + std::vector unpaired_devices; + for (auto& device : unpaired_devices_) { + unpaired_devices.push_back(device.Clone()); + } + scoped_bluetooth_config_test_helper_.fake_discovered_devices_provider() + ->SetDiscoveredDevices(std::move(unpaired_devices)); + } + base::test::TaskEnvironment task_environment_; + std::vector unpaired_devices_; + size_t num_devices_created_ = 0u; + chromeos::bluetooth_config::ScopedBluetoothConfigTestHelper scoped_bluetooth_config_test_helper_; @@ -220,5 +272,185 @@ TEST_F(BluetoothHidDetectorImplTest, EXPECT_TRUE(IsDiscoverySessionActive()); } +TEST_F(BluetoothHidDetectorImplTest, AddDevices_TypeNotHid) { + std::string device_id1; + AddUnpairedDevice(&device_id1, DeviceType::kHeadset); + + std::string device_id2; + AddUnpairedDevice(&device_id2, DeviceType::kKeyboard); + + // Begin HID detection. |device_id1| should not be attempted to be paired + // with. + StartBluetoothHidDetection(); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(1u, GetDevicePairingHandlers().size()); + EXPECT_EQ(device_id2, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); +} + +TEST_F(BluetoothHidDetectorImplTest, AddDevices_TypeNotMissing) { + std::string device_id1; + AddUnpairedDevice(&device_id1, DeviceType::kMouse); + + std::string device_id2; + AddUnpairedDevice(&device_id2, DeviceType::kKeyboard); + + // Begin HID detection. |device_id1| should not be attempted to be paired + // with. + StartBluetoothHidDetection(/*is_pointer_missing=*/false); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(1u, GetDevicePairingHandlers().size()); + EXPECT_EQ(device_id2, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); +} + +TEST_F(BluetoothHidDetectorImplTest, AddDevices_BeforeStartingDetection) { + std::string device_id1; + AddUnpairedDevice(&device_id1, DeviceType::kMouse); + + std::string device_id2; + AddUnpairedDevice(&device_id2, DeviceType::kKeyboardMouseCombo); + + // Begin HID detection. |device_id1| should be attempted to be paired with. + StartBluetoothHidDetection(); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(1u, GetDevicePairingHandlers().size()); + EXPECT_EQ(device_id1, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); + + // Mock |device_id1| being paired. |device_id2| should be attempted to be + // paired with. + RemoveUnpairedDevice(device_id1); + GetDevicePairingHandlers()[0]->SimulatePairDeviceFinished( + /*failure_reason=*/absl::nullopt); + EXPECT_EQ(device_id2, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); + + // Mock |device_id2| being paired. + RemoveUnpairedDevice(device_id2); + GetDevicePairingHandlers()[0]->SimulatePairDeviceFinished( + /*failure_reason=*/absl::nullopt); + EXPECT_TRUE( + GetDevicePairingHandlers()[0]->current_pairing_device_id().empty()); +} + +TEST_F(BluetoothHidDetectorImplTest, + AddDevices_SeriallyAfterStartingDetection) { + StartBluetoothHidDetection(); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(1u, GetDevicePairingHandlers().size()); + EXPECT_TRUE( + GetDevicePairingHandlers()[0]->current_pairing_device_id().empty()); + + std::string device_id1; + AddUnpairedDevice(&device_id1, DeviceType::kTablet); + EXPECT_EQ(device_id1, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); + + // Mock |device_id1| being paired. + RemoveUnpairedDevice(device_id1); + GetDevicePairingHandlers()[0]->SimulatePairDeviceFinished( + /*failure_reason=*/absl::nullopt); + EXPECT_TRUE( + GetDevicePairingHandlers()[0]->current_pairing_device_id().empty()); + + std::string device_id2; + AddUnpairedDevice(&device_id2, DeviceType::kKeyboard); + EXPECT_EQ(device_id2, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); + + // Mock |device_id2| being paired. + RemoveUnpairedDevice(device_id2); + GetDevicePairingHandlers()[0]->SimulatePairDeviceFinished( + /*failure_reason=*/absl::nullopt); + EXPECT_TRUE( + GetDevicePairingHandlers()[0]->current_pairing_device_id().empty()); +} + +TEST_F(BluetoothHidDetectorImplTest, AddDevices_BatchAfterStartingDetection) { + StartBluetoothHidDetection(); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(1u, GetDevicePairingHandlers().size()); + EXPECT_TRUE( + GetDevicePairingHandlers()[0]->current_pairing_device_id().empty()); + + std::string device_id1; + AddUnpairedDevice(&device_id1, DeviceType::kMouse); + EXPECT_EQ(device_id1, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); + + std::string device_id2; + AddUnpairedDevice(&device_id2, DeviceType::kKeyboard); + + // Mock |device_id1| being paired. + RemoveUnpairedDevice(device_id1); + GetDevicePairingHandlers()[0]->SimulatePairDeviceFinished( + /*failure_reason=*/absl::nullopt); + EXPECT_EQ(device_id2, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); + + // Mock |device_id2| being paired. + RemoveUnpairedDevice(device_id2); + GetDevicePairingHandlers()[0]->SimulatePairDeviceFinished( + /*failure_reason=*/absl::nullopt); + EXPECT_TRUE( + GetDevicePairingHandlers()[0]->current_pairing_device_id().empty()); +} + +TEST_F(BluetoothHidDetectorImplTest, AdapterDisablesDuringPairing) { + std::string device_id1; + AddUnpairedDevice(&device_id1, DeviceType::kMouse); + + std::string device_id2; + AddUnpairedDevice(&device_id2, DeviceType::kKeyboard); + + // Begin HID detection. |device_id1| should be attempted to be paired with. + StartBluetoothHidDetection(); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(1u, GetDevicePairingHandlers().size()); + EXPECT_EQ(device_id1, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); + + // Mock the adapter disabling. + SetAdapterState(BluetoothSystemState::kDisabled); + EXPECT_FALSE(IsDiscoverySessionActive()); + + // Mock the adapter re-enabling Bluetooth. This should cause + // BluetoothHidDetector to start discovery again. The first device should be + // attempted to be paired with again. + SetAdapterState(BluetoothSystemState::kEnabled); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(2u, GetDevicePairingHandlers().size()); + EXPECT_EQ(device_id1, + GetDevicePairingHandlers()[1]->current_pairing_device_id()); +} + +TEST_F(BluetoothHidDetectorImplTest, DetectionStopsStartsDuringPairing) { + std::string device_id1; + AddUnpairedDevice(&device_id1, DeviceType::kMouse); + + std::string device_id2; + AddUnpairedDevice(&device_id2, DeviceType::kKeyboard); + + // Begin HID detection. |device_id1| should be attempted to be paired with. + StartBluetoothHidDetection(); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(1u, GetDevicePairingHandlers().size()); + EXPECT_EQ(device_id1, + GetDevicePairingHandlers()[0]->current_pairing_device_id()); + + // Stop detection. + StopBluetoothHidDetection(); + EXPECT_FALSE(IsDiscoverySessionActive()); + + // Start detection again. The first device should be attempted to be paired + // with again. + StartBluetoothHidDetection(); + EXPECT_TRUE(IsDiscoverySessionActive()); + EXPECT_EQ(2u, GetDevicePairingHandlers().size()); + EXPECT_EQ(device_id1, + GetDevicePairingHandlers()[1]->current_pairing_device_id()); +} + } // namespace hid_detection } // namespace ash diff --git a/chromeos/services/bluetooth_config/discovery_session_manager_impl_unittest.cc b/chromeos/services/bluetooth_config/discovery_session_manager_impl_unittest.cc index c506dbba6acb1d..9e5fbe6778fed6 100644 --- a/chromeos/services/bluetooth_config/discovery_session_manager_impl_unittest.cc +++ b/chromeos/services/bluetooth_config/discovery_session_manager_impl_unittest.cc @@ -432,7 +432,6 @@ TEST_F(DiscoverySessionManagerImplTest, MultipleClientsAttemptPairing) { // Finish the pairing with failure. device_pairing_handler1->SimulatePairDeviceFinished( device::ConnectionFailureReason::kFailed); - base::RunLoop().RunUntilIdle(); EXPECT_EQ(result, mojom::PairingResult::kNonAuthFailure); EXPECT_TRUE(delegate1->IsMojoPipeConnected()); EXPECT_TRUE(delegate1->pairing_handler().is_connected()); @@ -455,7 +454,6 @@ TEST_F(DiscoverySessionManagerImplTest, MultipleClientsAttemptPairing) { // Finish the pairing with success. device_pairing_handler1->SimulatePairDeviceFinished( /*failure_reason=*/absl::nullopt); - base::RunLoop().RunUntilIdle(); EXPECT_EQ(result, mojom::PairingResult::kSuccess); EXPECT_TRUE(delegate1->IsMojoPipeConnected()); EXPECT_TRUE(delegate1->pairing_handler().is_connected()); @@ -488,7 +486,6 @@ TEST_F(DiscoverySessionManagerImplTest, MultipleClientsAttemptPairing) { // Finish the pairing with success. device_pairing_handler2->SimulatePairDeviceFinished( /*failure_reason=*/absl::nullopt); - base::RunLoop().RunUntilIdle(); EXPECT_EQ(result, mojom::PairingResult::kSuccess); EXPECT_TRUE(delegate2->IsMojoPipeConnected()); EXPECT_TRUE(delegate2->pairing_handler().is_connected()); @@ -622,7 +619,6 @@ TEST_F(DiscoverySessionManagerImplTest, device_pairing_handler->SimulatePairDeviceFinished( /*failure_reason=*/absl::nullopt); - base::RunLoop().RunUntilIdle(); EXPECT_EQ(result, mojom::PairingResult::kSuccess); // |delegate| will still be connected. diff --git a/chromeos/services/bluetooth_config/fake_device_pairing_handler.cc b/chromeos/services/bluetooth_config/fake_device_pairing_handler.cc index fd2d8eb621def0..1b59bbd84180ac 100644 --- a/chromeos/services/bluetooth_config/fake_device_pairing_handler.cc +++ b/chromeos/services/bluetooth_config/fake_device_pairing_handler.cc @@ -4,6 +4,7 @@ #include "chromeos/services/bluetooth_config/fake_device_pairing_handler.h" +#include "base/run_loop.h" #include "chromeos/services/bluetooth_config/device_conversion_util.h" namespace chromeos { @@ -28,6 +29,7 @@ void FakeDevicePairingHandler::SimulatePairDeviceFinished( absl::optional failure_reason) { DCHECK(!current_pairing_device_id().empty()); FinishCurrentPairingRequest(failure_reason); + base::RunLoop().RunUntilIdle(); } void FakeDevicePairingHandler::SimulateFetchDeviceFinished( diff --git a/chromeos/services/bluetooth_config/fake_discovery_session_manager.cc b/chromeos/services/bluetooth_config/fake_discovery_session_manager.cc index 66aa3b9a926baa..1421151eb05fd6 100644 --- a/chromeos/services/bluetooth_config/fake_discovery_session_manager.cc +++ b/chromeos/services/bluetooth_config/fake_discovery_session_manager.cc @@ -4,8 +4,6 @@ #include "chromeos/services/bluetooth_config/fake_discovery_session_manager.h" -#include "chromeos/services/bluetooth_config/fake_device_pairing_handler.h" - namespace chromeos { namespace bluetooth_config { @@ -26,6 +24,7 @@ void FakeDiscoverySessionManager::SetIsDiscoverySessionActive(bool is_active) { if (is_discovery_session_active_) { NotifyDiscoveryStarted(); NotifyHasAtLeastOneDiscoverySessionChanged(is_discovery_session_active_); + NotifyDiscoveredDevicesListChanged(); } else { NotifyDiscoveryStoppedAndClearActiveClients(); // DiscoverySessionStatusObservers would have been notified by the above @@ -47,8 +46,10 @@ std::unique_ptr FakeDiscoverySessionManager::CreateDevicePairingHandler( AdapterStateController* adapter_state_controller, mojo::PendingReceiver receiver) { - return std::make_unique(std::move(receiver), - adapter_state_controller); + auto fake_device_pairing_handler = std::make_unique( + std::move(receiver), adapter_state_controller); + device_pairing_handlers_.push_back(fake_device_pairing_handler.get()); + return fake_device_pairing_handler; } } // namespace bluetooth_config diff --git a/chromeos/services/bluetooth_config/fake_discovery_session_manager.h b/chromeos/services/bluetooth_config/fake_discovery_session_manager.h index 9e34ebac7e92a9..f242a4211e8abb 100644 --- a/chromeos/services/bluetooth_config/fake_discovery_session_manager.h +++ b/chromeos/services/bluetooth_config/fake_discovery_session_manager.h @@ -7,6 +7,7 @@ #include "chromeos/services/bluetooth_config/discovered_devices_provider.h" #include "chromeos/services/bluetooth_config/discovery_session_manager.h" +#include "chromeos/services/bluetooth_config/fake_device_pairing_handler.h" namespace chromeos { namespace bluetooth_config { @@ -25,6 +26,10 @@ class FakeDiscoverySessionManager : public DiscoverySessionManager { using DiscoverySessionManager::HasAtLeastOneDiscoveryClient; + std::vector& device_pairing_handlers() { + return device_pairing_handlers_; + } + private: // DiscoverySessionManager: void OnHasAtLeastOneDiscoveryClientChanged() override; @@ -33,6 +38,8 @@ class FakeDiscoverySessionManager : public DiscoverySessionManager { mojo::PendingReceiver receiver) override; bool is_discovery_session_active_ = false; + + std::vector device_pairing_handlers_; }; } // namespace bluetooth_config