This is the fix for StartDiscovery/Connect/Disconnect/StartDiscovery.
PiperOrigin-RevId: 424866263
diff --git a/cpp/platform/impl/windows/bluetooth_classic_medium.cc b/cpp/platform/impl/windows/bluetooth_classic_medium.cc
index 4f8a7db..f1f781e 100644
--- a/cpp/platform/impl/windows/bluetooth_classic_medium.cc
+++ b/cpp/platform/impl/windows/bluetooth_classic_medium.cc
@@ -97,9 +97,13 @@
void BluetoothClassicMedium::InitializeDeviceWatcher() {
// create watcher
+ const winrt::param::iterable<winrt::hstring> RequestedProperties =
+ winrt::single_threaded_vector<winrt::hstring>(
+ {winrt::to_hstring("System.Devices.Aep.IsPresent")});
+
device_watcher_ = DeviceInformation::CreateWatcher(
BLUETOOTH_SELECTOR, // aqsFilter
- nullptr, // additionalProperties
+ RequestedProperties, // additionalProperties
DeviceInformationKind::AssociationEndpoint); // kind
// An app must subscribe to all of the added, removed, and updated events to
@@ -177,8 +181,6 @@
return nullptr;
}
- device_watcher_.Stop();
-
EnterCriticalSection(&critical_section_);
std::unique_ptr<BluetoothSocket> rfcommSocket =
@@ -190,7 +192,7 @@
try {
rfcommSocket->Connect(requestedService.ConnectionHostName(),
- requestedService.ConnectionServiceName());
+ requestedService.ConnectionServiceName());
} catch (std::exception exception) {
// We will log and eat the exception since the caller
// expects nullptr if it fails
@@ -320,6 +322,8 @@
bool BluetoothClassicMedium::StartScanning() {
if (!IsWatcherStarted()) {
+ discovered_devices_by_id_.clear();
+
// The Start method can only be called when the DeviceWatcher is in the
// Created, Stopped or Aborted state.
auto status = device_watcher_.Status();
@@ -360,32 +364,37 @@
// Create an iterator for the internal list
std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>>::const_iterator
- it = devices_by_id_.find(deviceInfo.Id());
+ it = discovered_devices_by_id_.find(deviceInfo.Id());
// Add to our internal list if necessary
- if (it == devices_by_id_.end()) {
- // Create a bluetooth device out of this id
- winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync(
- deviceInfo.Id())
- .Completed(
- [this, deviceInfo, wbd = std::move(windowsBluetoothDevice)](
- auto&& async,
- winrt::Windows::Foundation::AsyncStatus status) {
- EnterCriticalSection(&critical_section_);
-
- std::unique_ptr<BluetoothDevice> bluetoothDevice =
- std::make_unique<BluetoothDevice>(async.get());
-
- devices_by_id_[deviceInfo.Id()] = std::move(bluetoothDevice);
-
- if (discovery_callback_.device_discovered_cb != nullptr) {
- discovery_callback_.device_discovered_cb(
- *devices_by_id_[deviceInfo.Id()]);
- }
-
- LeaveCriticalSection(&critical_section_);
- });
+ if (it != discovered_devices_by_id_.end()) {
+ // We're already tracking this one
+ return winrt::fire_and_forget();
}
+
+ // Create a bluetooth device out of this id
+ winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync(
+ deviceInfo.Id())
+ .Completed([this, deviceInfo](
+ winrt::Windows::Foundation::IAsyncOperation<
+ winrt::Windows::Devices::Bluetooth::BluetoothDevice>
+ bluetoothDevice,
+ winrt::Windows::Foundation::AsyncStatus status) {
+ EnterCriticalSection(&critical_section_);
+
+ std::unique_ptr<BluetoothDevice> bluetoothDeviceP =
+ std::make_unique<BluetoothDevice>(bluetoothDevice.get());
+
+ discovered_devices_by_id_[deviceInfo.Id()] =
+ std::move(bluetoothDeviceP);
+
+ if (discovery_callback_.device_discovered_cb != nullptr) {
+ discovery_callback_.device_discovered_cb(
+ *discovered_devices_by_id_[deviceInfo.Id()]);
+ }
+
+ LeaveCriticalSection(&critical_section_);
+ });
}
return winrt::fire_and_forget();
@@ -393,10 +402,30 @@
winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate) {
- if (IsWatcherStarted()) {
- // TODO(jfcarroll): Check for device name change
+ EnterCriticalSection(&critical_section_);
+
+ if (!IsWatcherStarted()) {
+ // Spurious call, watcher has stopped or wasn't started
+ LeaveCriticalSection(&critical_section_);
+ return winrt::fire_and_forget();
}
+ auto it = discovered_devices_by_id_.find(deviceInfoUpdate.Id());
+
+ if (it == discovered_devices_by_id_.end()) {
+ LeaveCriticalSection(&critical_section_);
+ // Not tracking this device
+ return winrt::fire_and_forget();
+ }
+
+ if (deviceInfoUpdate.Properties().HasKey(
+ winrt::to_hstring("System.ItemNameDisplay"))) {
+ discovery_callback_.device_name_changed_cb(
+ *discovered_devices_by_id_[deviceInfoUpdate.Id()]);
+ }
+
+ LeaveCriticalSection(&critical_section_);
+
return winrt::fire_and_forget();
}
@@ -404,14 +433,17 @@
DeviceWatcher sender, DeviceInformationUpdate deviceInfo) {
EnterCriticalSection(&critical_section_);
- if (IsWatcherStarted()) {
- if (discovery_callback_.device_lost_cb != nullptr) {
- discovery_callback_.device_lost_cb(*devices_by_id_[deviceInfo.Id()]);
- }
-
- devices_by_id_.erase(deviceInfo.Id());
+ if (!IsWatcherStarted()) {
+ return winrt::fire_and_forget();
}
+ if (discovery_callback_.device_lost_cb != nullptr) {
+ discovery_callback_.device_lost_cb(
+ *discovered_devices_by_id_[deviceInfo.Id()]);
+ }
+
+ discovered_devices_by_id_.erase(deviceInfo.Id());
+
LeaveCriticalSection(&critical_section_);
return winrt::fire_and_forget();
diff --git a/cpp/platform/impl/windows/bluetooth_classic_medium.h b/cpp/platform/impl/windows/bluetooth_classic_medium.h
index a5d9692..2d05ef1 100644
--- a/cpp/platform/impl/windows/bluetooth_classic_medium.h
+++ b/cpp/platform/impl/windows/bluetooth_classic_medium.h
@@ -173,7 +173,8 @@
// hstring is the only type of string winrt understands.
// https://docs.microsoft.com/en-us/uwp/cpp-ref-for-winrt/hstring
- std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>> devices_by_id_;
+ std::map<winrt::hstring, std::unique_ptr<BluetoothDevice>>
+ discovered_devices_by_id_;
// CRITICAL_SECTION is a lightweight synchronization mechanism
// https://docs.microsoft.com/en-us/windows/win32/sync/critical-section-objects
diff --git a/cpp/platform/impl/windows/bluetooth_classic_socket.cc b/cpp/platform/impl/windows/bluetooth_classic_socket.cc
index 3ce04b3..cda204e 100644
--- a/cpp/platform/impl/windows/bluetooth_classic_socket.cc
+++ b/cpp/platform/impl/windows/bluetooth_classic_socket.cc
@@ -23,10 +23,6 @@
BluetoothSocket::BluetoothSocket(StreamSocket streamSocket)
: windows_socket_(streamSocket) {
- bluetooth_device_ = std::make_unique<BluetoothDevice>(
- winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromHostNameAsync(
- windows_socket_.Information().RemoteHostName())
- .get());
input_stream_ =
std::make_unique<BluetoothInputStream>(windows_socket_.InputStream());
output_stream_ =