Implement RetroactivePairingDetector

PiperOrigin-RevId: 538319791
This commit is contained in:
Qin Wang
2023-06-06 16:18:38 -07:00
committed by Copybara-Service
parent aabc521454
commit ba740c9a5c
17 changed files with 481 additions and 28 deletions
+1 -1
View File
@@ -119,9 +119,9 @@ cc_test(
":mediums",
"//internal/platform:comm",
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform/implementation/g3", # build_cleaner: keep
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/strings",
"@com_google_googletest//:gtest_main",
],
)
@@ -34,6 +34,57 @@ bool BluetoothClassic::IsAvailableLocked() const {
return medium_.IsValid() && adapter_.IsValid() && adapter_.IsEnabled();
}
void BluetoothClassic::AddObserver(BluetoothClassicMedium::Observer* observer) {
MutexLock lock(&mutex_);
medium_.AddObserver(observer);
}
void BluetoothClassic::RemoveObserver(
BluetoothClassicMedium::Observer* observer) {
MutexLock lock(&mutex_);
medium_.RemoveObserver(observer);
}
bool BluetoothClassic::StartDiscovery() {
MutexLock lock(&mutex_);
if (!radio_.IsEnabled()) {
NEARBY_LOGS(INFO) << "Can't discover BT devices because BT isn't enabled.";
return false;
}
if (!IsAvailableLocked()) {
NEARBY_LOGS(INFO)
<< "Can't discover BT devices because BT isn't available.";
return false;
}
if (!medium_.StartDiscovery({})) {
NEARBY_LOGS(INFO) << "Failed to start discovery of BT devices.";
return false;
}
// Mark the fact that we're currently performing a Bluetooth scan.
is_scanning = true;
return true;
}
bool BluetoothClassic::StopDiscovery() {
MutexLock lock(&mutex_);
if (!IsDiscovering()) {
NEARBY_LOGS(INFO)
<< "Can't stop discovery of BT devices because it never started.";
return false;
}
if (!medium_.StopDiscovery()) {
NEARBY_LOGS(INFO) << "Failed to stop discovery of Bluetooth devices.";
return false;
}
is_scanning = false;
return true;
}
bool BluetoothClassic::IsDiscovering() const { return is_scanning; }
std::unique_ptr<BluetoothPairing> BluetoothClassic::CreatePairing(
absl::string_view public_address) {
MutexLock lock(&mutex_);
@@ -32,6 +32,17 @@ class BluetoothClassic {
// Returns true, if BT communications are supported by a platform.
bool IsAvailable() const ABSL_LOCKS_EXCLUDED(mutex_);
void AddObserver(BluetoothClassicMedium::Observer* observer);
void RemoveObserver(BluetoothClassicMedium::Observer* observer);
// Enables BT discovery mode to observer any discoverable device in range.
// Returns true, if discovery mode was enabled, false otherwise.
bool StartDiscovery() ABSL_LOCKS_EXCLUDED(mutex_);
// Disables BT discovery mode.
// Returns true, if discovery mode was previously enabled, false otherwise.
bool StopDiscovery() ABSL_LOCKS_EXCLUDED(mutex_);
// Returns a new BluetoothPairing instance to handle the pairing process
// with the remote device.
std::unique_ptr<BluetoothPairing> CreatePairing(
@@ -43,11 +54,15 @@ class BluetoothClassic {
// Same as IsAvailable(), but must be called with mutex_ held.
bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Returns true if device is currently in discovery mode.
bool IsDiscovering() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
mutable Mutex mutex_;
BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_);
BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){
radio_.GetBluetoothAdapter()};
BluetoothClassicMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_};
bool is_scanning ABSL_GUARDED_BY(mutex_) = false;
};
} // namespace fastpair
@@ -16,11 +16,74 @@
#include "gtest/gtest.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/medium_environment.h"
namespace nearby {
namespace fastpair {
namespace {
class BluetoothClassicMediumObserver
: public BluetoothClassicMedium ::Observer {
public:
explicit BluetoothClassicMediumObserver(
BluetoothClassic* bluetooth_classic, CountDownLatch* device_added_latch,
CountDownLatch* device_removed_latch,
CountDownLatch* device_paired_changed_latch)
: bluetooth_classic_(bluetooth_classic),
device_added_latch_(device_added_latch),
device_removed_latch_(device_removed_latch),
device_paired_changed_latch_(device_paired_changed_latch) {
bluetooth_classic_->AddObserver(this);
}
~BluetoothClassicMediumObserver() override {
bluetooth_classic_->RemoveObserver(this);
}
void DeviceAdded(BluetoothDevice& device) override {
if (!device_added_latch_) return;
device_added_latch_->CountDown();
}
void DeviceRemoved(BluetoothDevice& device) override {
if (!device_removed_latch_) return;
device_removed_latch_->CountDown();
}
void DevicePairedChanged(BluetoothDevice& device,
bool new_paired_status) override {
if (!device_paired_changed_latch_) return;
device_paired_changed_latch_->CountDown();
}
BluetoothClassic* bluetooth_classic_;
CountDownLatch* device_added_latch_;
CountDownLatch* device_removed_latch_;
CountDownLatch* device_paired_changed_latch_;
};
TEST(BluetoothClassicTest, CanStartAndStopDiscovery) {
MediumEnvironment::Instance().Start();
BluetoothRadio radio;
BluetoothClassic bluetooth_classic(radio);
BluetoothAdapter provider_adapter;
provider_adapter.SetStatus(BluetoothAdapter::Status::kEnabled);
provider_adapter.SetScanMode(
BluetoothAdapter::ScanMode::kConnectableDiscoverable);
BluetoothClassicMedium bt_provider(provider_adapter);
CountDownLatch device_added_latch(1);
CountDownLatch device_removed_latch(1);
BluetoothClassicMediumObserver observer(
&bluetooth_classic, &device_added_latch, &device_removed_latch, nullptr);
EXPECT_TRUE(bluetooth_classic.StartDiscovery());
device_added_latch.Await();
provider_adapter.SetStatus(BluetoothAdapter::Status::kDisabled);
device_removed_latch.Await();
EXPECT_TRUE(bluetooth_classic.StopDiscovery());
MediumEnvironment::Instance().Stop();
}
TEST(BluetoothClassicTest, CanCreatePairing) {
MediumEnvironment::Instance().Start();
@@ -36,7 +99,7 @@ TEST(BluetoothClassicTest, CanCreatePairing) {
MediumEnvironment::Instance().Stop();
}
TEST(BluetoothClassicTest, RemoteDeviceNotFound) {
TEST(BluetoothClassicTest, FailedToCreatePairingDueToRemoteDeviceNotFound) {
MediumEnvironment::Instance().Start();
BluetoothRadio radio;
BluetoothClassic bluetooth_classic(radio);
@@ -60,6 +123,8 @@ TEST(BluetoothClassicTest, RadioDisable) {
EXPECT_FALSE(bluetooth_classic.IsAvailable());
EXPECT_FALSE(
bluetooth_classic.CreatePairing(provider_adapter.GetMacAddress()));
EXPECT_FALSE(bluetooth_classic.StartDiscovery());
EXPECT_FALSE(bluetooth_classic.StopDiscovery());
}
TEST(BluetoothClassicTest, BluetoothAdapterDisable) {
@@ -73,6 +138,8 @@ TEST(BluetoothClassicTest, BluetoothAdapterDisable) {
EXPECT_FALSE(bluetooth_classic.IsAvailable());
EXPECT_FALSE(
bluetooth_classic.CreatePairing(adapter_provider.GetMacAddress()));
EXPECT_FALSE(bluetooth_classic.StartDiscovery());
EXPECT_FALSE(bluetooth_classic.StopDiscovery());
}
TEST(BluetoothClassicTest, GetMedium) {
+7
View File
@@ -18,9 +18,12 @@ cc_library(
name = "retroactive",
srcs = [
"retroactive.cc",
"retroactive_pairing_detector_impl.cc",
],
hdrs = [
"retroactive.h",
"retroactive_pairing_detector.h",
"retroactive_pairing_detector_impl.h",
],
compatible_with = ["//buildenv/target:non_prod"],
visibility = [
@@ -30,10 +33,14 @@ cc_library(
deps = [
"//fastpair:fast_pair_controller",
"//fastpair/common",
"//fastpair/internal/mediums",
"//fastpair/message_stream",
"//fastpair/pairing",
"//internal/base",
"//internal/platform:comm",
"//internal/platform:types",
"//third_party/magic_enum",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
],
@@ -0,0 +1,41 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_H_
#include "fastpair/common/fast_pair_device.h"
namespace nearby {
namespace fastpair {
// A RetroactivePairingDetector instance is responsible for detecting Fast Pair
// devices that can be paired retroactively, and notifying observers of this
// device.
class RetroactivePairingDetector {
public:
class Observer {
public:
virtual ~Observer() = default;
virtual void OnRetroactivePairFound(FastPairDevice& device) = 0;
};
virtual ~RetroactivePairingDetector() = default;
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
};
} // namespace fastpair
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_H_
@@ -0,0 +1,105 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "fastpair/retroactive/retroactive_pairing_detector_impl.h"
#include <ios>
#include "fastpair/internal/mediums/mediums.h"
#include "fastpair/pairing/pairer_broker.h"
namespace nearby {
namespace fastpair {
RetroactivePairingDetectorImpl::RetroactivePairingDetectorImpl(
Mediums& mediums, PairerBroker* pairer_broker)
: mediums_(mediums) {
pairer_broker->AddObserver(this);
mediums_.GetBluetoothClassic().AddObserver(this);
mediums_.GetBluetoothClassic().StartDiscovery();
}
RetroactivePairingDetectorImpl::~RetroactivePairingDetectorImpl() {
mediums_.GetBluetoothClassic().RemoveObserver(this);
mediums_.GetBluetoothClassic().StopDiscovery();
}
void RetroactivePairingDetectorImpl::AddObserver(
RetroactivePairingDetector::Observer* observer) {
observers_.AddObserver(observer);
}
void RetroactivePairingDetectorImpl::RemoveObserver(
RetroactivePairingDetector::Observer* observer) {
observers_.RemoveObserver(observer);
}
void RetroactivePairingDetectorImpl::OnDevicePaired(FastPairDevice& device) {
// The classic address is assigned to the Device during the
// initial Fast Pair pairing protocol and if it doesn't exist,
// then it wasn't properly paired during initial Fast Pair
// pairing.
if (!device.GetPublicAddress().has_value()) {
return;
}
// The Bluetooth Adapter system event `DevicePairedChanged` fires before
// Fast Pair's `OnDevicePaired`, and a Fast Pair pairing is expected to have
// both events. If a device is Fast Paired, it is already inserted in the
// |potential_retroactive_addresses_| in `DevicePairedChanged`; we need to
// remove it to prevent a false positive.
if (potential_retroactive_addresses_.contains(
device.GetPublicAddress().value())) {
NEARBY_LOGS(INFO)
<< __func__
<< ": paired with initial pairing, removing device at address = "
<< device.GetPublicAddress().value();
potential_retroactive_addresses_.erase(device.GetPublicAddress().value());
}
}
void RetroactivePairingDetectorImpl::DevicePairedChanged(
BluetoothDevice& device, bool new_paired_status) {
NEARBY_LOGS(INFO) << __func__
<< " Device paired changed, name = " << device.GetName()
<< " address = " << device.GetMacAddress()
<< " new_paired_status = " << std::boolalpha
<< new_paired_status;
// This event fires whenever a device pairing has changed with
// the BluetoothClassicMedium.
// If the |new_paired_status| is false, it means a device was unpaired,
// so we early return since it would not be a device to retroactively pair to.
if (!new_paired_status) {
return;
}
// Both classic paired and Fast paired devices call this function, so we
// have to add the device to |potential_retroactive_addresses_|. We expect
// devices paired via Fast Pair to always call `OnDevicePaired` after calling
// this function, which will remove the device from
// |potential_retroactive_addresses_|.
potential_retroactive_addresses_.insert(device.GetMacAddress());
// In order to confirm that this device is a retroactive pairing, we need to
// first check if it has already been saved to the user's account. If it has
// already been saved, we don't want to prompt the user to save a device
// again.
// TODO(b/285047010): check if device has already been saved to the user's
// account
// TODO(Janusz) Add implementation for AttemptRetroactivePairing
}
} // namespace fastpair
} // namespace nearby
@@ -0,0 +1,60 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_IMPL_H_
#define THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_IMPL_H_
#include <string>
#include "absl/container/flat_hash_set.h"
#include "fastpair/internal/mediums/mediums.h"
#include "fastpair/pairing/pairer_broker.h"
#include "fastpair/retroactive/retroactive_pairing_detector.h"
#include "internal/base/observer_list.h"
#include "internal/platform/bluetooth_classic.h"
namespace nearby {
namespace fastpair {
class RetroactivePairingDetectorImpl : public RetroactivePairingDetector,
public BluetoothClassicMedium ::Observer,
public PairerBroker::Observer {
public:
RetroactivePairingDetectorImpl(Mediums& mediums, PairerBroker* pairer_broker);
RetroactivePairingDetectorImpl(const RetroactivePairingDetectorImpl&) =
delete;
RetroactivePairingDetectorImpl& operator=(
const RetroactivePairingDetectorImpl&) = delete;
~RetroactivePairingDetectorImpl() override;
// RetroactivePairingDetector:
void AddObserver(RetroactivePairingDetector::Observer* observer) override;
void RemoveObserver(RetroactivePairingDetector::Observer* observer) override;
// BluetoothClassicMedium :: Observer
void DevicePairedChanged(BluetoothDevice& device,
bool new_paired_status) override;
// PairerBroker::Observer
void OnDevicePaired(FastPairDevice& device) override;
private:
Mediums& mediums_;
ObserverList<RetroactivePairingDetector::Observer> observers_;
absl::flat_hash_set<std::string> potential_retroactive_addresses_;
};
} // namespace fastpair
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_FASTPAIR_RETROACTIVE_RETROACTIVE_PAIRING_DETECTOR_IMPL_H_
+1
View File
@@ -226,6 +226,7 @@ cc_library(
":logging",
":types",
":uuid",
"//internal/base",
"//internal/platform/implementation:comm",
"//internal/test",
"@com_google_absl//absl/container:flat_hash_map",
@@ -45,6 +45,39 @@ constexpr FeatureFlags kTestCases[] = {
},
};
class BluetoothClassicMediumObserver
: public BluetoothClassicMedium ::Observer {
public:
explicit BluetoothClassicMediumObserver(
CountDownLatch* device_added_latch, CountDownLatch* device_removed_latch,
CountDownLatch* device_paired_changed_latch)
: device_added_latch_(device_added_latch),
device_removed_latch_(device_removed_latch),
device_paired_changed_latch_(device_paired_changed_latch) {}
void DeviceAdded(BluetoothDevice& device) override {
if (!device_added_latch_) return;
device_added_latch_->CountDown();
}
void DeviceRemoved(BluetoothDevice& device) override {
if (!device_removed_latch_) return;
device_removed_latch_->CountDown();
}
void DevicePairedChanged(BluetoothDevice& device,
bool new_paired_status) override {
if (!device_paired_changed_latch_) return;
paired_status_ = new_paired_status;
device_paired_changed_latch_->CountDown();
}
CountDownLatch* device_added_latch_;
CountDownLatch* device_removed_latch_;
CountDownLatch* device_paired_changed_latch_;
bool paired_status_ = false;
};
class BluetoothClassicMediumTest
: public ::testing::TestWithParam<FeatureFlags> {
protected:
@@ -304,6 +337,12 @@ TEST_F(BluetoothClassicMediumTest, CanStartDiscovery) {
adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
CountDownLatch found_latch(1);
CountDownLatch lost_latch(1);
CountDownLatch device_added_latch(1);
CountDownLatch device_removed_latch(1);
BluetoothClassicMediumObserver observer(&device_added_latch,
&device_removed_latch, nullptr);
bt_a_->AddObserver(&observer);
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch](BluetoothDevice& device) {
@@ -322,9 +361,11 @@ TEST_F(BluetoothClassicMediumTest, CanStartDiscovery) {
EXPECT_EQ(adapter_b_->GetScanMode(),
BluetoothAdapter::ScanMode::kConnectableDiscoverable);
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
EXPECT_TRUE(device_added_latch.Await(absl::Milliseconds(1000)).result());
adapter_b_->SetStatus(BluetoothAdapter::Status::kDisabled);
EXPECT_FALSE(adapter_b_->IsEnabled());
EXPECT_TRUE(lost_latch.Await(absl::Milliseconds(1000)).result());
EXPECT_TRUE(device_removed_latch.Await(absl::Milliseconds(1000)).result());
}
TEST_F(BluetoothClassicMediumTest, CanStopDiscovery) {
@@ -417,6 +458,10 @@ TEST_F(BluetoothClassicMediumTest, BluetoothPairingSuccess) {
CountDownLatch paired_latch(1);
CountDownLatch initiated_latch(1);
CountDownLatch error_latch(1);
CountDownLatch device_paired_latch(1);
BluetoothClassicMediumObserver observer(nullptr, nullptr,
&device_paired_latch);
bt_a_->AddObserver(&observer);
EXPECT_TRUE(bluetooth_pairing->InitiatePairing({
.on_paired_cb = [&]() { paired_latch.CountDown(); },
.on_pairing_error_cb =
@@ -442,6 +487,8 @@ TEST_F(BluetoothClassicMediumTest, BluetoothPairingSuccess) {
// Finishes pairing with remote device.
EXPECT_TRUE(bluetooth_pairing->FinishPairing(received_passkey));
paired_latch.Await();
device_paired_latch.Await();
EXPECT_TRUE(observer.paired_status_);
EXPECT_TRUE(bluetooth_pairing->IsPaired());
// Unpairs with remote device.
@@ -314,11 +314,12 @@ api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice(
void BluetoothClassicMedium::AddObserver(
api::BluetoothClassicMedium::Observer* observer) {
// TODO(b/269521993): Implement observer callbacks.
MediumEnvironment::Instance().AddObserver(observer);
}
void BluetoothClassicMedium::RemoveObserver(
api::BluetoothClassicMedium::Observer* observer) {
// TODO(b/269521993): Implement observer callbacks.
MediumEnvironment::Instance().RemoveObserver(observer);
}
} // namespace g3
@@ -20,6 +20,7 @@
#include <codecvt>
#include <fstream>
#include <functional>
#include <ios>
#include <locale>
#include <map>
#include <memory>
@@ -560,11 +561,6 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
return winrt::fire_and_forget();
}
// Represents a Bluetooth device.
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothdevice?view=winrt-20348
std::unique_ptr<winrt::Windows::Devices::Bluetooth::BluetoothDevice>
windowsBluetoothDevice;
// Create an iterator for the internal list
std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>>::const_iterator
it = discovered_devices_by_id_.find(deviceInfo.Id());
@@ -587,11 +583,14 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
discovered_devices_by_id_[deviceInfo.Id()] = std::move(bluetoothDeviceP);
NEARBY_LOGS(INFO) << __func__ << ": Notifying bluetooth device added";
if (discovery_callback_.device_discovered_cb != nullptr) {
discovery_callback_.device_discovered_cb(
*discovered_devices_by_id_[deviceInfo.Id()]);
}
for (auto& observer : observers_.GetObservers()) {
observer->DeviceAdded(*discovered_devices_by_id_[deviceInfo.Id()]);
}
return winrt::fire_and_forget();
}
@@ -619,6 +618,7 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
return winrt::fire_and_forget();
}
// https://learn.microsoft.com/en-us/windows/uwp/devices-sensors/device-information-properties#associationendpoint-properties
if (properties.HasKey(L"System.ItemNameDisplay")) {
// we need to really change the name of the bluetooth device
std::string new_device_name = InspectableReader::ReadString(
@@ -627,17 +627,29 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
if (it->second->GetName() == new_device_name) {
NEARBY_LOGS(INFO)
<< "Device name is same as old name, ignore the update.";
return {};
} else {
it->second->SetName(new_device_name);
NEARBY_LOGS(INFO)
<< "Updated device name:"
<< discovered_devices_by_id_[deviceInfoUpdate.Id()]->GetName();
discovery_callback_.device_name_changed_cb(
*discovered_devices_by_id_[deviceInfoUpdate.Id()]);
}
}
it->second->SetName(new_device_name);
NEARBY_LOGS(INFO)
<< "Updated device name:"
<< discovered_devices_by_id_[deviceInfoUpdate.Id()]->GetName();
discovery_callback_.device_name_changed_cb(
*discovered_devices_by_id_[deviceInfoUpdate.Id()]);
// Indicates if the device is currently paired.
if (properties.HasKey(L"System.Devices.Aep.IsPaired")) {
bool new_paired_status = InspectableReader::ReadBoolean(
properties.Lookup(L"System.Devices.Aep.IsPaired"));
NEARBY_LOGS(INFO) << __func__
<< ": Notifying device paired changed: " << std::boolalpha
<< new_paired_status;
for (auto& observer : observers_.GetObservers()) {
observer->DevicePairedChanged(
*discovered_devices_by_id_[deviceInfoUpdate.Id()], new_paired_status);
}
}
return winrt::fire_and_forget();
@@ -662,11 +674,16 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed(
return winrt::fire_and_forget();
}
NEARBY_LOGS(INFO) << __func__ << ": Notifying bluetooth device removed";
if (discovery_callback_.device_lost_cb != nullptr) {
discovery_callback_.device_lost_cb(
*discovered_devices_by_id_[deviceInfo.Id()]);
}
for (auto& observer : observers_.GetObservers()) {
observer->DeviceRemoved(*discovered_devices_by_id_[deviceInfo.Id()]);
}
discovered_devices_by_id_.erase(deviceInfo.Id());
return winrt::fire_and_forget();
@@ -19,6 +19,7 @@
#include <memory>
#include <string>
#include "internal/base/observer_list.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/implementation/windows/bluetooth_adapter.h"
#include "internal/platform/implementation/windows/bluetooth_classic_device.h"
@@ -152,12 +153,12 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
api::BluetoothDevice& remote_device) override;
void AddObserver(Observer* observer) override {
// TODO(b/269521993): Implement.
observers_.AddObserver(observer);
}
// Removes an observer. It's OK to remove an unregistered observer.
void RemoveObserver(Observer* observer) override {
// TODO(b/269521993): Implement.
observers_.RemoveObserver(observer);
}
private:
@@ -218,6 +219,7 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
std::unique_ptr<BluetoothServerSocket> server_socket_ = nullptr;
BluetoothServerSocket* raw_server_socket_ = nullptr;
bool is_radio_discoverable_ = false;
ObserverList<Observer> observers_;
};
} // namespace windows
@@ -29,7 +29,7 @@ namespace windows {
class ConditionVariable : public api::ConditionVariable {
public:
explicit ConditionVariable(api::Mutex* mutex)
: mutex_(&(static_cast<windows::Mutex*>(mutex))->mutex_) {}
: mutex_(&(static_cast<windows::Mutex*>(mutex))->GetMutex()) {}
~ConditionVariable() override = default;
Exception Wait() override {
+39 -5
View File
@@ -167,8 +167,12 @@ void MediumEnvironment::OnBluetoothDeviceStateChanged(
// Store device name, and report it as discovered.
info.devices.emplace(&device, name);
if (enable_notifications_) {
RunOnMediumEnvironmentThread(
[&info, &device]() { info.callback.device_discovered_cb(device); });
RunOnMediumEnvironmentThread([&]() {
info.callback.device_discovered_cb(device);
for (auto& observer : observers_.GetObservers()) {
observer->DeviceAdded(device);
}
});
}
}
} else {
@@ -190,8 +194,11 @@ void MediumEnvironment::OnBluetoothDeviceStateChanged(
} else {
// Device is in discovery mode, so we are reporting it anyway.
if (enable_notifications_) {
RunOnMediumEnvironmentThread([&info, &device]() {
RunOnMediumEnvironmentThread([&]() {
info.callback.device_discovered_cb(device);
for (auto& observer : observers_.GetObservers()) {
observer->DeviceAdded(device);
}
});
}
}
@@ -200,8 +207,12 @@ void MediumEnvironment::OnBluetoothDeviceStateChanged(
// Known device is turned off.
// Erase it from the map, and report as lost.
if (enable_notifications_) {
RunOnMediumEnvironmentThread(
[&info, &device]() { info.callback.device_lost_cb(device); });
RunOnMediumEnvironmentThread([&]() {
info.callback.device_lost_cb(device);
for (auto& observer : observers_.GetObservers()) {
observer->DeviceRemoved(device);
}
});
}
info.devices.erase(item);
}
@@ -1199,6 +1210,11 @@ bool MediumEnvironment::SetPairingState(api::BluetoothDevice* device,
latch.CountDown();
});
latch.Await();
if (enable_notifications_) {
for (auto& observer : observers_.GetObservers()) {
observer->DevicePairedChanged(*device, true);
}
}
return updated;
}
@@ -1262,6 +1278,11 @@ bool MediumEnvironment::FinishPairing(api::BluetoothDevice* device) {
pairing_context->pairing_error.value());
} else {
pairing_context->is_paired = true;
if (enable_notifications_) {
for (auto& observer : observers_.GetObservers()) {
observer->DevicePairedChanged(*device, true);
}
}
pairing_context->pairing_callback.on_paired_cb();
}
return finshed;
@@ -1306,4 +1327,17 @@ void MediumEnvironment::ClearBluetoothDevicesForPairing() {
if (!enabled_) return;
RunOnMediumEnvironmentThread([&]() { devices_pairing_contexts_.clear(); });
}
void MediumEnvironment::AddObserver(
api::BluetoothClassicMedium::Observer* observer) {
if (!enabled_) return;
observers_.AddObserver(observer);
}
void MediumEnvironment::RemoveObserver(
api::BluetoothClassicMedium::Observer* observer) {
if (!enabled_) return;
observers_.RemoveObserver(observer);
}
} // namespace nearby
+5
View File
@@ -26,6 +26,7 @@
#include "absl/container/flat_hash_set.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "internal/base/observer_list.h"
#include "internal/platform/borrowable.h"
#include "internal/platform/implementation/ble.h"
#include "internal/platform/implementation/ble_v2.h"
@@ -384,6 +385,9 @@ class MediumEnvironment {
// Clears the map `devices_pairing_contexts_`.
void ClearBluetoothDevicesForPairing();
void AddObserver(api::BluetoothClassicMedium::Observer* observer);
void RemoveObserver(api::BluetoothClassicMedium::Observer* observer);
private:
struct BluetoothMediumContext {
BluetoothDiscoveryCallback callback;
@@ -514,6 +518,7 @@ class MediumEnvironment {
bool use_valid_peer_connection_ = true;
absl::Duration peer_connection_latency_ = absl::ZeroDuration();
std::unique_ptr<FakeClock> simulated_clock_ ABSL_GUARDED_BY(mutex_);
ObserverList<api::BluetoothClassicMedium::Observer> observers_;
};
} // namespace nearby
+1 -1
View File
@@ -418,4 +418,4 @@ enum PowerLevel {
}
// LINT.ThenChange(
// //depot/google3/java/com/google/android/gmscore/integ/client/nearby/src/com/google/android/gms/nearby/connection/PowerLevel.java
// )
// )