diff --git a/internal/platform/BUILD b/internal/platform/BUILD index d38291a2..9d77cc82 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -421,6 +421,7 @@ cc_library( "//internal/platform/implementation:platform", "@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/functional:any_invocable", + "@com_google_absl//absl/status", "@com_google_absl//absl/strings", "@com_google_absl//absl/types:optional", ], diff --git a/internal/platform/ble_v2.cc b/internal/platform/ble_v2.cc index 2dbaf67d..f7c197a1 100644 --- a/internal/platform/ble_v2.cc +++ b/internal/platform/ble_v2.cc @@ -18,6 +18,7 @@ #include #include +#include "absl/status/status.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/implementation/ble_v2.h" #include "internal/platform/logging.h" @@ -37,6 +38,26 @@ bool BleV2Medium::StartAdvertising( bool BleV2Medium::StopAdvertising() { return impl_->StopAdvertising(); } +std::unique_ptr +BleV2Medium::StartAdvertisingTmp( + const api::ble_v2::BleAdvertisementData& advertising_data, + api::ble_v2::AdvertiseParameters advertise_set_parameters, + api::ble_v2::BleMedium::AdvertisingCallback callback) { + if (impl_->StartAdvertising(advertising_data, advertise_set_parameters)) { + callback.start_advertising_result(absl::OkStatus()); + } else { + callback.start_advertising_result( + absl::InternalError("Failed to start advertising")); + return nullptr; + } + return std::make_unique( + api::ble_v2::BleMedium::AdvertisingSession{.stop_advertising = [this] { + return impl_->StopAdvertising() + ? absl::OkStatus() + : absl::InternalError("Failed to stop advertising"); + }}); +} + std::unique_ptr BleV2Medium::StartAdvertising( const api::ble_v2::BleAdvertisementData& advertising_data, @@ -102,6 +123,44 @@ bool BleV2Medium::StopScanning() { return impl_->StopScanning(); } +std::unique_ptr +BleV2Medium::StartScanningTmp( + const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level, + api::ble_v2::BleMedium::ScanningCallback callback) { + // auto scan_callback = std::move(callback.advertisement_found_cb); + MutexLock lock(&mutex_); + + if (impl_->StartScanning( + service_uuid, tx_power_level, + api::ble_v2::BleMedium::ScanCallback{ + .advertisement_found_cb = + [this, &callback]( + api::ble_v2::BlePeripheral& peripheral, + BleAdvertisementData advertisement_data) { + MutexLock lock(&mutex_); + if (!peripherals_.contains(&peripheral)) { + NEARBY_LOGS(INFO) + << "There is no need to callback due to peripheral " + "impl=" + << &peripheral << ", which already exists."; + peripherals_.insert(&peripheral); + } + callback.advertisement_found_cb(peripheral, + advertisement_data); + }, + })) { + callback.start_scanning_result(absl::OkStatus()); + } else { + callback.start_scanning_result(absl::InternalError("Failed to start scan")); + return nullptr; + } + return std::make_unique( + api::ble_v2::BleMedium::ScanningSession{.stop_scanning = [this]() { + return impl_->StopScanning() + ? absl::OkStatus() + : absl::InternalError("Failed to stop advertising"); + }}); +} std::unique_ptr BleV2Medium::StartScanning(const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level, diff --git a/internal/platform/ble_v2.h b/internal/platform/ble_v2.h index b6798709..fc369d96 100644 --- a/internal/platform/ble_v2.h +++ b/internal/platform/ble_v2.h @@ -280,26 +280,51 @@ class BleV2Medium final { adapter_(adapter) {} // Returns true once the BLE advertising has been initiated. + // This interface will be deprecated soon. + // TODO(b/271305977) remove this function. + // Use 'unique_ptr StartAdvertisingTmp' instead. bool StartAdvertising( const api::ble_v2::BleAdvertisementData& advertising_data, api::ble_v2::AdvertiseParameters advertise_parameters); + // This interface will be deprecated soon. + // TODO(b/271305977) remove this function. bool StopAdvertising(); + // Temp interface for windows client to use before windows has native impl + // for 'unique_ptr StartAdvertising'. + // TODO(b/271305977) remove this function. + std::unique_ptr + StartAdvertisingTmp(const api::ble_v2::BleAdvertisementData& advertising_data, + api::ble_v2::AdvertiseParameters advertise_set_parameters, + api::ble_v2::BleMedium::AdvertisingCallback callback); + std::unique_ptr StartAdvertising( const api::ble_v2::BleAdvertisementData& advertising_data, api::ble_v2::AdvertiseParameters advertise_set_parameters, api::ble_v2::BleMedium::AdvertisingCallback callback); // Returns true once the BLE scan has been initiated. + // This interface will be deprecated soon. + // TODO(b/271305977) remove this function. + // Use 'unique_ptr StartScanningTmp' instead. bool StartScanning(const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level, ScanCallback callback); + // This interface will be deprecated soon. + // TODO(b/271305977) remove this function. bool StopScanning(); std::unique_ptr StartScanning( const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level, api::ble_v2::BleMedium::ScanningCallback callback); + // Temp interface for windows client to use before windows has native impl + // for 'unique_ptr StartScanning'. + // TODO(b/271305977) remove this function. + std::unique_ptr StartScanningTmp( + const Uuid& service_uuid, api::ble_v2::TxPowerLevel tx_power_level, + api::ble_v2::BleMedium::ScanningCallback callback); + // Starts Gatt Server for waiting to client connection. std::unique_ptr StartGattServer( ServerGattConnectionCallback callback); diff --git a/internal/platform/ble_v2_test.cc b/internal/platform/ble_v2_test.cc index ba0d16ee..58eb9498 100644 --- a/internal/platform/ble_v2_test.cc +++ b/internal/platform/ble_v2_test.cc @@ -21,6 +21,7 @@ #include "gmock/gmock.h" #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" +#include "absl/status/status.h" #include "internal/platform/bluetooth_adapter.h" #include "internal/platform/count_down_latch.h" #include "internal/platform/implementation/ble_v2.h" @@ -443,6 +444,56 @@ TEST_F(BleV2MediumTest, CanStartAsyncScanningAndAdvertising) { env_.Stop(); } +TEST_F(BleV2MediumTest, CanStartAsyncScanningAndAdvertisingWithTmpImpl) { + env_.Start(); + BluetoothAdapter adapter_a; + BluetoothAdapter adapter_b; + BleV2Medium ble_a(adapter_a); + BleV2Medium ble_b(adapter_b); + Uuid service_uuid(1234, 5678); + ByteArray advertisement_bytes{std::string(kAdvertisementString)}; + ByteArray advertisement_header_bytes{std::string(kAdvertisementHeaderString)}; + CountDownLatch found_latch(1); + + std::unique_ptr scanning_session = + ble_a.StartScanningTmp( + service_uuid, kTxPowerLevel, + api::ble_v2::BleMedium::ScanningCallback{ + .advertisement_found_cb = + [&](api::ble_v2::BlePeripheral& peripheral, + BleAdvertisementData advertisement_data) -> void { + found_latch.CountDown(); + }, + }); + + // Succeed to start regular advertisement. + BleAdvertisementData advertising_data; + advertising_data.is_extended_advertisement = false; + advertising_data.service_data = {{service_uuid, advertisement_header_bytes}}; + std::unique_ptr adv_session = + ble_b.StartAdvertisingTmp( + advertising_data, + {.tx_power_level = kTxPowerLevel, .is_connectable = true}, + {.start_advertising_result = [](absl::Status) {}}); + EXPECT_NE(adv_session, nullptr); + + EXPECT_TRUE(env_.GetBleV2MediumStatus(*ble_a.GetImpl()).value().is_scanning); + EXPECT_TRUE( + env_.GetBleV2MediumStatus(*ble_b.GetImpl()).value().is_advertising); + EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); + EXPECT_OK(scanning_session->stop_scanning()); + + EXPECT_OK(adv_session->stop_advertising()); + EXPECT_FALSE(env_.GetBleV2MediumStatus(*ble_a.GetImpl()).value().is_scanning); + EXPECT_FALSE( + env_.GetBleV2MediumStatus(*ble_b.GetImpl()).value().is_advertising); + env_.UnregisterBleV2Medium(*ble_a.GetImpl()); + env_.UnregisterBleV2Medium(*ble_b.GetImpl()); + EXPECT_EQ(env_.GetBleV2MediumStatus(*ble_a.GetImpl()), absl::nullopt); + EXPECT_EQ(env_.GetBleV2MediumStatus(*ble_b.GetImpl()), absl::nullopt); + env_.Stop(); +} + TEST_F(BleV2MediumTest, CanStartGattServer) { env_.Start(); BluetoothAdapter adapter;