mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Internal refactor
PiperOrigin-RevId: 705210963
This commit is contained in:
committed by
Copybara-Service
parent
9e464937a8
commit
0d05883b76
@@ -16,25 +16,21 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <codecvt>
|
||||
#include <functional>
|
||||
#include <ios>
|
||||
#include <locale>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <regex> // NOLINT
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/cancellation_flag_listener.h"
|
||||
#include "internal/platform/exception.h"
|
||||
#include "internal/platform/feature_flags.h"
|
||||
#include "internal/platform/implementation/bluetooth_adapter.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"
|
||||
#include "internal/platform/implementation/windows/bluetooth_classic_server_socket.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_classic_socket.h"
|
||||
#include "internal/platform/implementation/windows/bluetooth_pairing.h"
|
||||
#include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h"
|
||||
@@ -119,57 +115,6 @@ BluetoothClassicMedium::BluetoothClassicMedium(
|
||||
|
||||
BluetoothClassicMedium::~BluetoothClassicMedium() {}
|
||||
|
||||
void BluetoothClassicMedium::OnScanModeChanged(
|
||||
BluetoothAdapter::ScanMode scan_mode) {
|
||||
LOG(INFO) << __func__ << ": OnScanModeChanged is called with scanMode: "
|
||||
<< static_cast<int>(scan_mode);
|
||||
|
||||
if (scan_mode == scan_mode_) {
|
||||
LOG(INFO) << __func__ << ": No change of scan mode.";
|
||||
return;
|
||||
}
|
||||
|
||||
scan_mode_ = scan_mode;
|
||||
bool radio_discoverable =
|
||||
scan_mode_ == BluetoothAdapter::ScanMode::kConnectableDiscoverable;
|
||||
|
||||
if (bluetooth_adapter_.GetName().size() >
|
||||
kAndroidDiscoverableBluetoothNameMaxLength) {
|
||||
// If the name longer than the android limitation, always set the value to
|
||||
// false.
|
||||
radio_discoverable = false;
|
||||
}
|
||||
|
||||
if (is_radio_discoverable_ == radio_discoverable) {
|
||||
LOG(INFO) << __func__ << ": No change of radio discovery.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (rfcomm_provider_ == nullptr) {
|
||||
LOG(WARNING) << __func__ << ": No advertising.";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
rfcomm_provider_.StopAdvertising();
|
||||
rfcomm_provider_.StartAdvertising(
|
||||
raw_server_socket_->stream_socket_listener(), radio_discoverable);
|
||||
is_radio_discoverable_ = radio_discoverable;
|
||||
return;
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": OnScanModeChanged exception: " << exception.what();
|
||||
return;
|
||||
} catch (const winrt::hresult_error& ex) {
|
||||
LOG(ERROR) << __func__ << ": OnScanModeChanged exception: " << ex.code()
|
||||
<< ": " << winrt::to_string(ex.message());
|
||||
return;
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothClassicMedium::StartDiscovery(
|
||||
BluetoothClassicMedium::DiscoveryCallback discovery_callback) {
|
||||
LOG(INFO) << "StartDiscovery is called.";
|
||||
@@ -197,53 +142,6 @@ bool BluetoothClassicMedium::StopDiscovery() {
|
||||
return result;
|
||||
}
|
||||
|
||||
void BluetoothClassicMedium::InitializeDeviceWatcher() {
|
||||
try {
|
||||
// create watcher
|
||||
const winrt::param::iterable<winrt::hstring> requested_properties =
|
||||
winrt::single_threaded_vector<winrt::hstring>(
|
||||
{winrt::to_hstring("System.Devices.Aep.IsPresent"),
|
||||
winrt::to_hstring("System.Devices.Aep.DeviceAddress")});
|
||||
|
||||
device_watcher_ = DeviceInformation::CreateWatcher(
|
||||
kBluetoothSelector, // aqsFilter
|
||||
requested_properties, // additionalProperties
|
||||
DeviceInformationKind::AssociationEndpoint); // kind
|
||||
|
||||
// An app must subscribe to all of the added, removed, and updated events
|
||||
// to be notified when there are device additions, removals or updates. If
|
||||
// an app handles only the added event, it will not receive an update if a
|
||||
// device is added to the system after the initial device enumeration
|
||||
// completes. register event handlers before starting the watcher
|
||||
|
||||
// Event that is raised when a device is added to the collection enumerated
|
||||
// by the DeviceWatcher.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.added?view=winrt-20348
|
||||
device_watcher_.Added({this, &BluetoothClassicMedium::DeviceWatcher_Added});
|
||||
|
||||
// Event that is raised when a device is updated in the collection of
|
||||
// enumerated devices.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.updated?view=winrt-20348
|
||||
device_watcher_.Updated(
|
||||
{this, &BluetoothClassicMedium::DeviceWatcher_Updated});
|
||||
|
||||
// Event that is raised when a device is removed from the collection of
|
||||
// enumerated devices.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.removed?view=winrt-20348
|
||||
device_watcher_.Removed(
|
||||
{this, &BluetoothClassicMedium::DeviceWatcher_Removed});
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": InitializeDeviceWatcher exception: " << exception.what();
|
||||
} catch (const winrt::hresult_error& ex) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": InitializeDeviceWatcher exception: " << ex.code() << ": "
|
||||
<< winrt::to_string(ex.message());
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
|
||||
api::BluetoothDevice& remote_device, const std::string& service_uuid,
|
||||
CancellationFlag* cancellation_flag) {
|
||||
@@ -273,8 +171,8 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto remote_device_to_connect_ = dynamic_cast<BluetoothDevice*>(
|
||||
GetRemoteDevice(remote_device.GetMacAddress()));
|
||||
BluetoothDevice* remote_device_to_connect_ =
|
||||
GetRemoteDeviceInternal(remote_device.GetMacAddress());
|
||||
|
||||
if (remote_device_to_connect_ == nullptr ||
|
||||
remote_device_to_connect_->GetId().empty()) {
|
||||
@@ -341,6 +239,55 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
|
||||
}
|
||||
}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord
|
||||
//
|
||||
// service_uuid is the canonical textual representation
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a
|
||||
// type 3 name-based
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
|
||||
// UUID.
|
||||
//
|
||||
// Returns nullptr error.
|
||||
std::unique_ptr<api::BluetoothServerSocket>
|
||||
BluetoothClassicMedium::ListenForService(const std::string& service_name,
|
||||
const std::string& service_uuid) {
|
||||
LOG(INFO) << "ListenForService is called with service name: " << service_name
|
||||
<< ".";
|
||||
if (service_uuid.empty()) {
|
||||
LOG(ERROR) << __func__ << ": service_uuid was empty.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (service_name.empty()) {
|
||||
LOG(ERROR) << __func__ << ": service_name was empty.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
service_name_ = service_name;
|
||||
service_uuid_ = service_uuid;
|
||||
|
||||
scan_mode_ = bluetooth_adapter_.GetScanMode();
|
||||
|
||||
LOG(INFO) << __func__ << ": scan_mode: " << static_cast<int>(scan_mode_);
|
||||
bool radio_discoverable =
|
||||
scan_mode_ == BluetoothAdapter::ScanMode::kConnectableDiscoverable;
|
||||
|
||||
bool result = StartAdvertising(radio_discoverable);
|
||||
|
||||
if (!result) {
|
||||
LOG(ERROR) << __func__ << ": Failed to start listening.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(server_socket_);
|
||||
}
|
||||
|
||||
api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice(
|
||||
const std::string& mac_address) {
|
||||
LOG(INFO) << "GetRemoteDevice is called with mac_address: " << mac_address;
|
||||
return GetRemoteDeviceInternal(mac_address);
|
||||
}
|
||||
|
||||
std::unique_ptr<api::BluetoothPairing> BluetoothClassicMedium::CreatePairing(
|
||||
api::BluetoothDevice& remote_device) {
|
||||
VLOG(1) << __func__ << ": Start to createPairing with device: "
|
||||
@@ -371,6 +318,104 @@ std::unique_ptr<api::BluetoothPairing> BluetoothClassicMedium::CreatePairing(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BluetoothClassicMedium::InitializeDeviceWatcher() {
|
||||
try {
|
||||
// create watcher
|
||||
const winrt::param::iterable<winrt::hstring> requested_properties =
|
||||
winrt::single_threaded_vector<winrt::hstring>(
|
||||
{winrt::to_hstring("System.Devices.Aep.IsPresent"),
|
||||
winrt::to_hstring("System.Devices.Aep.DeviceAddress")});
|
||||
|
||||
device_watcher_ = DeviceInformation::CreateWatcher(
|
||||
kBluetoothSelector, // aqsFilter
|
||||
requested_properties, // additionalProperties
|
||||
DeviceInformationKind::AssociationEndpoint); // kind
|
||||
|
||||
// An app must subscribe to all of the added, removed, and updated events
|
||||
// to be notified when there are device additions, removals or updates. If
|
||||
// an app handles only the added event, it will not receive an update if a
|
||||
// device is added to the system after the initial device enumeration
|
||||
// completes. register event handlers before starting the watcher
|
||||
|
||||
// Event that is raised when a device is added to the collection enumerated
|
||||
// by the DeviceWatcher.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.added?view=winrt-20348
|
||||
device_watcher_.Added({this, &BluetoothClassicMedium::DeviceWatcher_Added});
|
||||
|
||||
// Event that is raised when a device is updated in the collection of
|
||||
// enumerated devices.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.updated?view=winrt-20348
|
||||
device_watcher_.Updated(
|
||||
{this, &BluetoothClassicMedium::DeviceWatcher_Updated});
|
||||
|
||||
// Event that is raised when a device is removed from the collection of
|
||||
// enumerated devices.
|
||||
// https://docs.microsoft.com/en-us/uwp/api/windows.devices.enumeration.devicewatcher.removed?view=winrt-20348
|
||||
device_watcher_.Removed(
|
||||
{this, &BluetoothClassicMedium::DeviceWatcher_Removed});
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": InitializeDeviceWatcher exception: " << exception.what();
|
||||
} catch (const winrt::hresult_error& ex) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": InitializeDeviceWatcher exception: " << ex.code() << ": "
|
||||
<< winrt::to_string(ex.message());
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
}
|
||||
}
|
||||
|
||||
void BluetoothClassicMedium::OnScanModeChanged(
|
||||
BluetoothAdapter::ScanMode scan_mode) {
|
||||
LOG(INFO) << __func__ << ": OnScanModeChanged is called with scanMode: "
|
||||
<< static_cast<int>(scan_mode);
|
||||
|
||||
if (scan_mode == scan_mode_) {
|
||||
LOG(INFO) << __func__ << ": No change of scan mode.";
|
||||
return;
|
||||
}
|
||||
|
||||
scan_mode_ = scan_mode;
|
||||
bool radio_discoverable =
|
||||
scan_mode_ == BluetoothAdapter::ScanMode::kConnectableDiscoverable;
|
||||
|
||||
if (bluetooth_adapter_.GetName().size() >
|
||||
kAndroidDiscoverableBluetoothNameMaxLength) {
|
||||
// If the name longer than the android limitation, always set the value to
|
||||
// false.
|
||||
radio_discoverable = false;
|
||||
}
|
||||
|
||||
if (is_radio_discoverable_ == radio_discoverable) {
|
||||
LOG(INFO) << __func__ << ": No change of radio discovery.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (rfcomm_provider_ == nullptr) {
|
||||
LOG(WARNING) << __func__ << ": No advertising.";
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
rfcomm_provider_.StopAdvertising();
|
||||
rfcomm_provider_.StartAdvertising(
|
||||
raw_server_socket_->stream_socket_listener(), radio_discoverable);
|
||||
is_radio_discoverable_ = radio_discoverable;
|
||||
return;
|
||||
} catch (std::exception exception) {
|
||||
LOG(ERROR) << __func__
|
||||
<< ": OnScanModeChanged exception: " << exception.what();
|
||||
return;
|
||||
} catch (const winrt::hresult_error& ex) {
|
||||
LOG(ERROR) << __func__ << ": OnScanModeChanged exception: " << ex.code()
|
||||
<< ": " << winrt::to_string(ex.message());
|
||||
return;
|
||||
} catch (...) {
|
||||
LOG(ERROR) << __func__ << ": Unknown exception.";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothClassicMedium::HaveAccess(winrt::hstring device_id) {
|
||||
if (device_id.empty()) {
|
||||
return false;
|
||||
@@ -438,72 +483,74 @@ bool BluetoothClassicMedium::CheckSdp(RfcommDeviceService requested_service) {
|
||||
}
|
||||
}
|
||||
|
||||
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord
|
||||
//
|
||||
// service_uuid is the canonical textual representation
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Format) of a
|
||||
// type 3 name-based
|
||||
// (https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_3_and_5_(namespace_name-based))
|
||||
// UUID.
|
||||
//
|
||||
// Returns nullptr error.
|
||||
std::unique_ptr<api::BluetoothServerSocket>
|
||||
BluetoothClassicMedium::ListenForService(const std::string& service_name,
|
||||
const std::string& service_uuid) {
|
||||
LOG(INFO) << "ListenForService is called with service name: " << service_name
|
||||
<< ".";
|
||||
if (service_uuid.empty()) {
|
||||
LOG(ERROR) << __func__ << ": service_uuid was empty.";
|
||||
return nullptr;
|
||||
bool BluetoothClassicMedium::HasRemoteDevice(const std::string& mac_address) {
|
||||
absl::MutexLock lock(&devices_map_mutex_);
|
||||
if (IsWatcherStarted()) {
|
||||
return mac_address_to_bluetooth_device_map_.contains(mac_address);
|
||||
} else {
|
||||
return cached_bluetooth_devices_map_.contains(mac_address);
|
||||
}
|
||||
|
||||
if (service_name.empty()) {
|
||||
LOG(ERROR) << __func__ << ": service_name was empty.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
service_name_ = service_name;
|
||||
service_uuid_ = service_uuid;
|
||||
|
||||
scan_mode_ = bluetooth_adapter_.GetScanMode();
|
||||
|
||||
LOG(INFO) << __func__ << ": scan_mode: " << static_cast<int>(scan_mode_);
|
||||
bool radio_discoverable =
|
||||
scan_mode_ == BluetoothAdapter::ScanMode::kConnectableDiscoverable;
|
||||
|
||||
bool result = StartAdvertising(radio_discoverable);
|
||||
|
||||
if (!result) {
|
||||
LOG(ERROR) << __func__ << ": Failed to start listening.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(server_socket_);
|
||||
}
|
||||
|
||||
api::BluetoothDevice* BluetoothClassicMedium::GetRemoteDevice(
|
||||
bool BluetoothClassicMedium::RemoveRemoteDevice(
|
||||
const std::string& mac_address) {
|
||||
absl::MutexLock lock(&devices_map_mutex_);
|
||||
|
||||
auto it = mac_address_to_bluetooth_device_map_.find(mac_address);
|
||||
|
||||
if (it == mac_address_to_bluetooth_device_map_.end()) {
|
||||
LOG(WARNING) << __func__ << ": Bluetooth device " << mac_address
|
||||
<< " is not in list. create it";
|
||||
auto bluetooth_device = std::make_unique<BluetoothDevice>(mac_address);
|
||||
|
||||
if (IsWatcherStarted()) {
|
||||
mac_address_to_bluetooth_device_map_[mac_address] =
|
||||
std::move(bluetooth_device);
|
||||
return mac_address_to_bluetooth_device_map_[mac_address].get();
|
||||
} else {
|
||||
cached_bluetooth_devices_map_[mac_address] = std::move(bluetooth_device);
|
||||
return cached_bluetooth_devices_map_[mac_address].get();
|
||||
}
|
||||
if (it != mac_address_to_bluetooth_device_map_.end()) {
|
||||
auto node = mac_address_to_bluetooth_device_map_.extract(mac_address);
|
||||
removed_bluetooth_devices_map_[mac_address] = std::move(node.mapped());
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Bluetooth device " << mac_address
|
||||
<< " is in cache";
|
||||
return false;
|
||||
}
|
||||
|
||||
return it->second.get();
|
||||
bool BluetoothClassicMedium::AssignRemoteDevice(
|
||||
const std::string& mac_address, std::unique_ptr<BluetoothDevice> device) {
|
||||
absl::MutexLock lock(&devices_map_mutex_);
|
||||
auto result = mac_address_to_bluetooth_device_map_.insert_or_assign(
|
||||
mac_address, std::move(device));
|
||||
return result.second;
|
||||
}
|
||||
|
||||
BluetoothDevice* BluetoothClassicMedium::GetRemoteDeviceInternal(
|
||||
const std::string& mac_address) {
|
||||
absl::MutexLock lock(&devices_map_mutex_);
|
||||
if (IsWatcherStarted()) {
|
||||
auto it = mac_address_to_bluetooth_device_map_.find(mac_address);
|
||||
|
||||
if (it == mac_address_to_bluetooth_device_map_.end()) {
|
||||
LOG(WARNING) << __func__ << ": Bluetooth device " << mac_address
|
||||
<< " is not in list. create it";
|
||||
auto bluetooth_device = std::make_unique<BluetoothDevice>(mac_address);
|
||||
|
||||
mac_address_to_bluetooth_device_map_[mac_address] =
|
||||
std::move(bluetooth_device);
|
||||
auto result = mac_address_to_bluetooth_device_map_.insert_or_assign(
|
||||
mac_address, std::move(bluetooth_device));
|
||||
|
||||
return result.first->second.get();
|
||||
}
|
||||
|
||||
return it->second.get();
|
||||
|
||||
} else {
|
||||
auto it = cached_bluetooth_devices_map_.find(mac_address);
|
||||
|
||||
if (it == cached_bluetooth_devices_map_.end()) {
|
||||
LOG(WARNING) << __func__ << ": Bluetooth device " << mac_address
|
||||
<< " is not in cache list. create it";
|
||||
auto bluetooth_device = std::make_unique<BluetoothDevice>(mac_address);
|
||||
|
||||
auto result = cached_bluetooth_devices_map_.insert_or_assign(
|
||||
mac_address, std::move(bluetooth_device));
|
||||
|
||||
return result.first->second.get();
|
||||
}
|
||||
|
||||
return it->second.get();
|
||||
}
|
||||
}
|
||||
|
||||
bool BluetoothClassicMedium::StartScanning() {
|
||||
@@ -514,16 +561,19 @@ bool BluetoothClassicMedium::StartScanning() {
|
||||
return false;
|
||||
}
|
||||
|
||||
mac_address_to_bluetooth_device_map_.clear();
|
||||
removed_bluetooth_devices_map_.clear();
|
||||
if (!cached_bluetooth_devices_map_.empty()) {
|
||||
for (auto& [mac_address, bluetooth_device] :
|
||||
cached_bluetooth_devices_map_) {
|
||||
mac_address_to_bluetooth_device_map_[mac_address] =
|
||||
std::move(bluetooth_device);
|
||||
}
|
||||
{
|
||||
absl::MutexLock lock(&devices_map_mutex_);
|
||||
mac_address_to_bluetooth_device_map_.clear();
|
||||
removed_bluetooth_devices_map_.clear();
|
||||
if (!cached_bluetooth_devices_map_.empty()) {
|
||||
for (auto& [mac_address, bluetooth_device] :
|
||||
cached_bluetooth_devices_map_) {
|
||||
mac_address_to_bluetooth_device_map_[mac_address] =
|
||||
std::move(bluetooth_device);
|
||||
}
|
||||
|
||||
cached_bluetooth_devices_map_.clear();
|
||||
cached_bluetooth_devices_map_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// The Start method can only be called when the DeviceWatcher is in the
|
||||
@@ -557,13 +607,16 @@ bool BluetoothClassicMedium::StopScanning() {
|
||||
winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
|
||||
DeviceWatcher sender, DeviceInformation device_info) {
|
||||
LOG(INFO) << "Device added " << winrt::to_string(device_info.Id());
|
||||
IMapView<winrt::hstring, IInspectable> properties = device_info.Properties();
|
||||
DumpDeviceInformation(properties);
|
||||
|
||||
if (!IsWatcherStarted()) {
|
||||
LOG(WARNING) << __func__ << ": Ignore the Bluetooth device "
|
||||
<< winrt::to_string(device_info.Id())
|
||||
<< " due to watcher not started.";
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
IMapView<winrt::hstring, IInspectable> properties = device_info.Properties();
|
||||
DumpDeviceInformation(properties);
|
||||
|
||||
// If device no item name, ignore it.
|
||||
if (!properties.HasKey(L"System.ItemNameDisplay")) {
|
||||
LOG(WARNING) << __func__ << ": Ignore the Bluetooth device "
|
||||
@@ -602,11 +655,7 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
|
||||
std::string mac_address =
|
||||
uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress());
|
||||
|
||||
// Create an iterator for the internal list
|
||||
auto it = mac_address_to_bluetooth_device_map_.find(mac_address);
|
||||
|
||||
// Add to our internal list if necessary
|
||||
if (it != mac_address_to_bluetooth_device_map_.end()) {
|
||||
if (HasRemoteDevice(mac_address)) {
|
||||
// We're already tracking this one
|
||||
LOG(WARNING) << __func__ << ": Bluetooth device " << mac_address
|
||||
<< " is alreay added.";
|
||||
@@ -616,23 +665,35 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Added(
|
||||
auto bluetooth_device =
|
||||
std::make_unique<BluetoothDevice>(native_bluetooth_device);
|
||||
|
||||
mac_address_to_bluetooth_device_map_[mac_address] =
|
||||
std::move(bluetooth_device);
|
||||
AssignRemoteDevice(mac_address, std::move(bluetooth_device));
|
||||
|
||||
api::BluetoothDevice* device = GetRemoteDeviceInternal(mac_address);
|
||||
if (device == nullptr) {
|
||||
LOG(ERROR) << __func__ << ": Failed to get remote device.";
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Notifying bluetooth device " << mac_address
|
||||
<< " added";
|
||||
if (discovery_callback_.device_discovered_cb != nullptr) {
|
||||
discovery_callback_.device_discovered_cb(
|
||||
*mac_address_to_bluetooth_device_map_[mac_address]);
|
||||
discovery_callback_.device_discovered_cb(*device);
|
||||
}
|
||||
for (auto& observer : observers_.GetObservers()) {
|
||||
observer->DeviceAdded(*mac_address_to_bluetooth_device_map_[mac_address]);
|
||||
observer->DeviceAdded(*device);
|
||||
}
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
|
||||
DeviceWatcher sender, DeviceInformationUpdate device_update_info) {
|
||||
LOG(INFO) << "Device updated " << winrt::to_string(device_update_info.Id());
|
||||
if (!IsWatcherStarted()) {
|
||||
LOG(WARNING) << __func__ << ": Ignore the Bluetooth device "
|
||||
<< winrt::to_string(device_update_info.Id())
|
||||
<< " due to watcher not started.";
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
auto native_bluetooth_device =
|
||||
::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync(
|
||||
device_update_info.Id())
|
||||
@@ -640,43 +701,39 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
|
||||
std::string mac_address =
|
||||
uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress());
|
||||
|
||||
auto it = mac_address_to_bluetooth_device_map_.find(mac_address);
|
||||
|
||||
if (it == mac_address_to_bluetooth_device_map_.end()) {
|
||||
if (!HasRemoteDevice(mac_address)) {
|
||||
LOG(WARNING) << __func__ << ": Bluetooth device " << mac_address
|
||||
<< " is not in list.";
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
LOG(INFO) << "Device updated name: "
|
||||
<< mac_address_to_bluetooth_device_map_[mac_address]->GetName()
|
||||
<< " (" << mac_address << ")";
|
||||
BluetoothDevice* device = GetRemoteDeviceInternal(mac_address);
|
||||
if (device == nullptr) {
|
||||
LOG(ERROR) << __func__ << ": Failed to get remote device.";
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
LOG(INFO) << "Device updated name: " << device->GetName() << " ("
|
||||
<< mac_address << ")";
|
||||
IMapView<winrt::hstring, IInspectable> properties =
|
||||
device_update_info.Properties();
|
||||
DumpDeviceInformation(properties);
|
||||
|
||||
if (!IsWatcherStarted()) {
|
||||
// Spurious call, watcher has stopped or wasn't started
|
||||
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(
|
||||
properties.Lookup(L"System.ItemNameDisplay"));
|
||||
|
||||
if (it->second->GetName() == new_device_name) {
|
||||
if (device->GetName() == new_device_name) {
|
||||
LOG(INFO) << "Device name is same as old name, ignore the update.";
|
||||
} else {
|
||||
it->second->SetName(new_device_name);
|
||||
device->SetName(new_device_name);
|
||||
|
||||
LOG(INFO) << "Updated device name:"
|
||||
<< mac_address_to_bluetooth_device_map_[mac_address]->GetName();
|
||||
LOG(INFO) << "Updated device name:" << device->GetName();
|
||||
|
||||
if (discovery_callback_.device_name_changed_cb != nullptr) {
|
||||
discovery_callback_.device_name_changed_cb(
|
||||
*mac_address_to_bluetooth_device_map_[mac_address]);
|
||||
discovery_callback_.device_name_changed_cb(*device);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -689,9 +746,7 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
|
||||
<< ": Notifying device paired changed: " << std::boolalpha
|
||||
<< new_paired_status;
|
||||
for (auto& observer : observers_.GetObservers()) {
|
||||
observer->DevicePairedChanged(
|
||||
*mac_address_to_bluetooth_device_map_[mac_address],
|
||||
new_paired_status);
|
||||
observer->DevicePairedChanged(*device, new_paired_status);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -700,6 +755,14 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Updated(
|
||||
|
||||
winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed(
|
||||
DeviceWatcher sender, DeviceInformationUpdate device_update_info) {
|
||||
LOG(INFO) << "Device removed " << winrt::to_string(device_update_info.Id());
|
||||
if (!IsWatcherStarted()) {
|
||||
LOG(WARNING) << __func__ << ": Ignore the Bluetooth device "
|
||||
<< winrt::to_string(device_update_info.Id())
|
||||
<< " due to watcher not started.";
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
auto native_bluetooth_device =
|
||||
::winrt::Windows::Devices::Bluetooth::BluetoothDevice::FromIdAsync(
|
||||
device_update_info.Id())
|
||||
@@ -712,34 +775,31 @@ winrt::fire_and_forget BluetoothClassicMedium::DeviceWatcher_Removed(
|
||||
|
||||
std::string mac_address =
|
||||
uint64_to_mac_address_string(native_bluetooth_device.BluetoothAddress());
|
||||
auto it = mac_address_to_bluetooth_device_map_.find(mac_address);
|
||||
|
||||
if (it == mac_address_to_bluetooth_device_map_.end()) {
|
||||
if (!HasRemoteDevice(mac_address)) {
|
||||
LOG(WARNING) << __func__ << ": Bluetooth device " << mac_address
|
||||
<< " is not in list.";
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
LOG(INFO) << "Device removed "
|
||||
<< mac_address_to_bluetooth_device_map_[mac_address]->GetName()
|
||||
<< " (" << mac_address << ")";
|
||||
api::BluetoothDevice* device = GetRemoteDeviceInternal(mac_address);
|
||||
|
||||
if (!IsWatcherStarted()) {
|
||||
if (device == nullptr) {
|
||||
LOG(ERROR) << __func__ << ": Failed to get remote device.";
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
LOG(INFO) << __func__ << ": Notifying bluetooth device removed";
|
||||
LOG(INFO) << __func__ << ": Notifying bluetooth device (" << mac_address
|
||||
<< ") removed";
|
||||
if (discovery_callback_.device_lost_cb != nullptr) {
|
||||
discovery_callback_.device_lost_cb(
|
||||
*mac_address_to_bluetooth_device_map_[mac_address]);
|
||||
discovery_callback_.device_lost_cb(*device);
|
||||
}
|
||||
|
||||
for (auto& observer : observers_.GetObservers()) {
|
||||
observer->DeviceRemoved(*mac_address_to_bluetooth_device_map_[mac_address]);
|
||||
observer->DeviceRemoved(*device);
|
||||
}
|
||||
|
||||
auto node = mac_address_to_bluetooth_device_map_.extract(mac_address);
|
||||
removed_bluetooth_devices_map_[mac_address] = std::move(node.mapped());
|
||||
RemoveRemoteDevice(mac_address);
|
||||
|
||||
return winrt::fire_and_forget();
|
||||
}
|
||||
|
||||
@@ -15,12 +15,12 @@
|
||||
#ifndef PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_
|
||||
#define PLATFORM_IMPL_WINDOWS_BLUETOOTH_CLASSIC_MEDIUM_H_
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/container/flat_hash_map.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "internal/base/observer_list.h"
|
||||
#include "internal/platform/cancellation_flag.h"
|
||||
#include "internal/platform/implementation/bluetooth_adapter.h"
|
||||
@@ -141,6 +141,17 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
|
||||
// Check to see that the device actually handles the requested service
|
||||
bool CheckSdp(RfcommDeviceService requested_service);
|
||||
|
||||
// Methods to handle bluetooth devices
|
||||
bool HasRemoteDevice(const std::string& mac_address)
|
||||
ABSL_LOCKS_EXCLUDED(devices_map_mutex_);
|
||||
bool RemoveRemoteDevice(const std::string& mac_address)
|
||||
ABSL_LOCKS_EXCLUDED(devices_map_mutex_);
|
||||
bool AssignRemoteDevice(const std::string& mac_address,
|
||||
std::unique_ptr<BluetoothDevice> device)
|
||||
ABSL_LOCKS_EXCLUDED(devices_map_mutex_);
|
||||
BluetoothDevice* GetRemoteDeviceInternal(const std::string& mac_address)
|
||||
ABSL_LOCKS_EXCLUDED(devices_map_mutex_);
|
||||
|
||||
BluetoothClassicMedium::DiscoveryCallback discovery_callback_;
|
||||
|
||||
::winrt::Windows::Devices::Enumeration::DeviceWatcher device_watcher_ =
|
||||
@@ -151,17 +162,21 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
|
||||
std::string service_name_;
|
||||
std::string service_uuid_;
|
||||
|
||||
absl::Mutex devices_map_mutex_;
|
||||
|
||||
// Map MAC address to bluetooth device.
|
||||
absl::flat_hash_map<std::string, std::unique_ptr<BluetoothDevice>>
|
||||
mac_address_to_bluetooth_device_map_;
|
||||
mac_address_to_bluetooth_device_map_ ABSL_GUARDED_BY(devices_map_mutex_);
|
||||
|
||||
// Track removed devices.
|
||||
absl::flat_hash_map<std::string, std::unique_ptr<BluetoothDevice>>
|
||||
removed_bluetooth_devices_map_;
|
||||
removed_bluetooth_devices_map_ ABSL_GUARDED_BY(devices_map_mutex_);
|
||||
;
|
||||
|
||||
// The caller may call to create Bluetooth device when scanning is off.
|
||||
absl::flat_hash_map<std::string, std::unique_ptr<BluetoothDevice>>
|
||||
cached_bluetooth_devices_map_;
|
||||
cached_bluetooth_devices_map_ ABSL_GUARDED_BY(devices_map_mutex_);
|
||||
;
|
||||
|
||||
BluetoothAdapter& bluetooth_adapter_;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user