From caa82a41d8a708ec3f8565fcfe10fb733997b4cb Mon Sep 17 00:00:00 2001 From: Guogang Li Date: Thu, 18 Jan 2024 09:53:30 -0800 Subject: [PATCH] Added flag control to Bluetooth update PiperOrigin-RevId: 599538193 --- .../flags/nearby_platform_feature_flags.h | 4 + .../windows/bluetooth_classic_device.cc | 76 ++++++++++++++++++- .../windows/bluetooth_classic_device.h | 6 +- .../windows/bluetooth_classic_socket.cc | 35 ++++++++- 4 files changed, 114 insertions(+), 7 deletions(-) diff --git a/internal/platform/flags/nearby_platform_feature_flags.h b/internal/platform/flags/nearby_platform_feature_flags.h index 51ef3437..c4ae6834 100644 --- a/internal/platform/flags/nearby_platform_feature_flags.h +++ b/internal/platform/flags/nearby_platform_feature_flags.h @@ -69,6 +69,10 @@ constexpr auto kWifiHotspotConnectionTimeoutMillis = constexpr auto kEnableIntelPieSdk = flags::Flag(kConfigPackage, "45428547", false); +// Enable/Disable new Bluetooth refactor +constexpr auto kEnableNewBluetoothRefactor = + flags::Flag(kConfigPackage, "45615156", false); + } // namespace nearby_platform_feature } // namespace config_package_nearby } // namespace platform diff --git a/internal/platform/implementation/windows/bluetooth_classic_device.cc b/internal/platform/implementation/windows/bluetooth_classic_device.cc index 390a1d30..0445e8ca 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_device.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_device.cc @@ -25,6 +25,8 @@ #include "absl/strings/string_view.h" #include "absl/time/clock.h" #include "absl/time/time.h" +#include "internal/flags/nearby_flags.h" +#include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.Rfcomm.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Enumeration.h" @@ -76,7 +78,79 @@ std::string BluetoothDevice::GetMacAddress() const { return mac_address_; } // Checks cache first, will check uncached if no result. RfcommDeviceService BluetoothDevice::GetRfcommServiceForIdAsync( - const RfcommServiceId serviceId) { + RfcommServiceId serviceId) { + if (nearby::NearbyFlags::GetInstance().GetBoolFlag( + platform::config_package_nearby::nearby_platform_feature:: + kEnableNewBluetoothRefactor)) { + return GetRfcommServiceForIdWithRetryAsync(serviceId); + } + + try { + NEARBY_LOGS(INFO) << __func__ << ": Get RF services for service id:" + << winrt::to_string(serviceId.AsString()); + + RfcommDeviceServicesResult rfcomm_device_services = nullptr; + // Try to get service from un cached mode. + auto rfcomm_device_services_async = + windows_bluetooth_device_.GetRfcommServicesForIdAsync( + serviceId, BluetoothCacheMode::Uncached); + + switch (rfcomm_device_services_async.wait_for( + TimeSpan(std::chrono::seconds(kBluetoothTimeoutInSeconds)))) { + case winrt::Windows::Foundation::AsyncStatus::Completed: + rfcomm_device_services = rfcomm_device_services_async.GetResults(); + break; + case winrt::Windows::Foundation::AsyncStatus::Started: + NEARBY_LOGS(ERROR) + << __func__ + << ": Failed to get RfcommDeviceService due to timeout."; + rfcomm_device_services_async.Cancel(); + return nullptr; + default: + NEARBY_LOGS(ERROR) + << __func__ + << ": Failed to get RfcommDeviceService due to unknown reasons."; + return nullptr; + } + + if (rfcomm_device_services != nullptr && + rfcomm_device_services.Services().Size() > 0) { + NEARBY_LOGS(INFO) << __func__ << ": Get " + << rfcomm_device_services.Services().Size() + << " services without cache."; + // found the matched service. + for (auto rfcomm_device_service : rfcomm_device_services.Services()) { + if (rfcomm_device_service.Device() != nullptr && + winrt::to_string(rfcomm_device_service.Device().DeviceId()) == + id_) { + NEARBY_LOGS(INFO) + << __func__ << ": Found service from no-cache mode."; + return rfcomm_device_service; + } + } + } + + NEARBY_LOGS(ERROR) + << __func__ + << ": Failed to get RfcommDeviceService due to no any services."; + return nullptr; + } catch (std::exception exception) { + NEARBY_LOGS(ERROR) << __func__ << ": Failed to get RfcommDeviceService: " + << exception.what(); + return nullptr; + } catch (const winrt::hresult_error& ex) { + NEARBY_LOGS(ERROR) << __func__ << ": RfcommDeviceService: " << ex.code() + << ", error message: " << winrt::to_string(ex.message()); + return nullptr; + } catch (...) { + NEARBY_LOGS(ERROR) << __func__ << ": Unknown exception."; + return nullptr; + } +} + +// Checks cache first, will check uncached if no result. +RfcommDeviceService BluetoothDevice::GetRfcommServiceForIdWithRetryAsync( + RfcommServiceId serviceId) { int check_service_count = 0; while (check_service_count < kCheckBluetoothServiceMaxTimes) { try { diff --git a/internal/platform/implementation/windows/bluetooth_classic_device.h b/internal/platform/implementation/windows/bluetooth_classic_device.h index 7c16e3c7..2c61029c 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_device.h +++ b/internal/platform/implementation/windows/bluetooth_classic_device.h @@ -77,10 +77,12 @@ class BluetoothDevice : public api::BluetoothDevice { void SetName(std::string name) { name_ = name; } RfcommDeviceService GetRfcommServiceForIdAsync( - const winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId - serviceId); + winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId serviceId); private: + RfcommDeviceService GetRfcommServiceForIdWithRetryAsync( + winrt::Windows::Devices::Bluetooth::Rfcomm::RfcommServiceId serviceId); + // https://docs.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothdevice?view=winrt-20348 winrt::Windows::Devices::Bluetooth::BluetoothDevice windows_bluetooth_device_; diff --git a/internal/platform/implementation/windows/bluetooth_classic_socket.cc b/internal/platform/implementation/windows/bluetooth_classic_socket.cc index 215719a0..705741a8 100644 --- a/internal/platform/implementation/windows/bluetooth_classic_socket.cc +++ b/internal/platform/implementation/windows/bluetooth_classic_socket.cc @@ -20,9 +20,13 @@ #include #include +#include "absl/time/clock.h" +#include "absl/time/time.h" +#include "internal/flags/nearby_flags.h" #include "internal/platform/byte_array.h" #include "internal/platform/exception.h" #include "internal/platform/feature_flags.h" +#include "internal/platform/flags/nearby_platform_feature_flags.h" #include "internal/platform/implementation/bluetooth_classic.h" #include "internal/platform/implementation/windows/bluetooth_classic_device.h" #include "internal/platform/implementation/windows/generated/winrt/Windows.Devices.Bluetooth.h" @@ -42,6 +46,9 @@ using ::winrt::Windows::Storage::Streams::Buffer; using ::winrt::Windows::Storage::Streams::IInputStream; using ::winrt::Windows::Storage::Streams::InputStreamOptions; using ::winrt::Windows::Storage::Streams::IOutputStream; + +constexpr int kMaxConnectRetryCount = 3; +constexpr absl::Duration kConnectInterval = absl::Seconds(3); } // namespace BluetoothSocket::BluetoothSocket(StreamSocket stream_socket) @@ -139,10 +146,30 @@ bool BluetoothSocket::Connect(HostName connection_host_name, NEARBY_LOGS(INFO) << __func__ << ": start to connect to bluetooth service:" << winrt::to_string(connection_service_name); - bool connect_result = - InternalConnect(connection_host_name, connection_service_name); - if (connect_result) { - return connect_result; + if (nearby::NearbyFlags::GetInstance().GetBoolFlag( + platform::config_package_nearby::nearby_platform_feature:: + kEnableNewBluetoothRefactor)) { + bool connect_result = + InternalConnect(connection_host_name, connection_service_name); + if (connect_result) { + return connect_result; + } + } else { + int connect_called_count = 0; + while (connect_called_count < kMaxConnectRetryCount) { + connect_called_count += 1; + bool connect_result = + InternalConnect(connection_host_name, connection_service_name); + if (connect_result) { + return connect_result; + } + + NEARBY_LOGS(WARNING) << __func__ + << ": Failed to connect bluetooth at the " + << connect_called_count << "th call."; + + absl::SleepFor(kConnectInterval); + } } NEARBY_LOGS(WARNING) << __func__ << ": Failed to connect bluetooth";