feat: add ble_v2 test in g3 platform

PiperOrigin-RevId: 786993987
This commit is contained in:
Mingshiou Wu
2025-07-25 00:07:27 -07:00
committed by Copybara-Service
parent 4b41512543
commit fcd3cb0fc3
6 changed files with 202 additions and 14 deletions
+1
View File
@@ -527,6 +527,7 @@ let package = Package(
"internal/platform/byte_array_test.cc",
"internal/platform/bluetooth_utils_test.cc",
"internal/platform/credential_storage_impl_test.cc",
"internal/platform/implementation/g3/ble_v2_test.cc",
"internal/platform/input_stream_test.cc",
"internal/platform/mac_address_test.cc",
"internal/platform/single_thread_executor_test.cc",
+16
View File
@@ -118,6 +118,22 @@ cc_library(
],
)
cc_test(
name = "comm_test",
srcs = ["ble_v2_test.cc"],
deps = [
":comm",
":g3",
"//internal/platform:base",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
"@com_google_googletest//:gtest_main",
],
)
cc_library(
name = "crypto",
testonly = True,
+9 -10
View File
@@ -148,19 +148,18 @@ Exception BleV2ServerSocket::DoClose() {
return {Exception::kSuccess};
}
BleV2Medium::BleV2Medium(api::BluetoothAdapter& adapter)
: adapter_(dynamic_cast<BluetoothAdapter*>(&adapter)) {
CHECK(adapter_);
adapter_->SetBleV2Medium(this);
BleV2Medium::BleV2Medium(BluetoothAdapter& adapter) : adapter_(adapter) {
CHECK(&adapter_);
adapter_.SetBleV2Medium(this);
is_extended_advertisements_available_ =
MediumEnvironment::Instance().IsBleExtendedAdvertisementsAvailable();
MediumEnvironment::Instance().RegisterBleV2Medium(*this,
adapter_->GetUniqueId());
adapter_.GetUniqueId());
}
BleV2Medium::~BleV2Medium() {
adapter_->SetBleV2Medium(nullptr);
adapter_.SetBleV2Medium(nullptr);
MediumEnvironment::Instance().UnregisterBleV2Medium(*this);
}
@@ -183,7 +182,7 @@ bool BleV2Medium::StartAdvertising(
absl::MutexLock lock(&mutex_);
MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising(
/*enabled=*/true, *this, adapter_->GetUniqueId(), advertising_data);
/*enabled=*/true, *this, adapter_.GetUniqueId(), advertising_data);
return true;
}
@@ -193,7 +192,7 @@ bool BleV2Medium::StopAdvertising() {
BleAdvertisementData empty_advertisement_data = {};
MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising(
/*enabled=*/false, *this, adapter_->GetUniqueId(),
/*enabled=*/false, *this, adapter_.GetUniqueId(),
empty_advertisement_data);
return true;
}
@@ -221,7 +220,7 @@ std::unique_ptr<BleV2Medium::AdvertisingSession> BleV2Medium::StartAdvertising(
}
absl::MutexLock lock(&mutex_);
MediumEnvironment::Instance().UpdateBleV2MediumForAdvertising(
/*enabled=*/true, *this, adapter_->GetUniqueId(), advertising_data);
/*enabled=*/true, *this, adapter_.GetUniqueId(), advertising_data);
return std::make_unique<AdvertisingSession>(
AdvertisingSession{.stop_advertising = [this] {
return StopAdvertising()
@@ -736,7 +735,7 @@ std::unique_ptr<api::ble_v2::BleSocket> BleV2Medium::Connect(
CancellationFlag* cancellation_flag) {
LOG(INFO) << "G3 Ble Connect [self]: medium=" << this
<< ", adapter=" << &GetAdapter()
<< ", peripheral id=" << adapter_->GetUniqueId()
<< ", peripheral id=" << adapter_.GetUniqueId()
<< ", service_id=" << service_id;
// First, find an instance of remote medium, that exposed this peripheral.
BleV2Medium* remote_medium = dynamic_cast<BleV2Medium*>(
+3 -3
View File
@@ -131,7 +131,7 @@ class BleV2ServerSocket : public api::ble_v2::BleServerSocket {
// Container of operations that can be performed over the BLE medium.
class BleV2Medium : public api::ble_v2::BleMedium {
public:
explicit BleV2Medium(api::BluetoothAdapter& adapter);
explicit BleV2Medium(BluetoothAdapter& adapter);
~BleV2Medium() override;
// Returns true once the Ble advertising has been initiated.
@@ -188,7 +188,7 @@ class BleV2Medium : public api::ble_v2::BleMedium {
bool IsExtendedAdvertisementsAvailable() override;
BluetoothAdapter& GetAdapter() { return *adapter_; }
BluetoothAdapter& GetAdapter() { return adapter_; }
private:
class GattClient;
@@ -304,7 +304,7 @@ class BleV2Medium : public api::ble_v2::BleMedium {
bool IsStopped(Borrowable<api::ble_v2::GattServer*> server);
absl::Mutex mutex_;
BluetoothAdapter* adapter_; // Our device adapter; read-only.
BluetoothAdapter& adapter_; // Our device adapter; read-only.
absl::flat_hash_map<std::string, BleV2ServerSocket*> server_sockets_
ABSL_GUARDED_BY(mutex_);
absl::flat_hash_set<std::pair<Uuid, std::uint32_t>>
@@ -0,0 +1,171 @@
// Copyright 2025 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 "internal/platform/implementation/g3/ble_v2.h"
#include <string>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/implementation/ble_v2.h"
#include "internal/platform/implementation/bluetooth_adapter.h"
#include "internal/platform/implementation/g3/bluetooth_adapter.h"
#include "internal/platform/uuid.h"
namespace nearby {
namespace g3 {
namespace {
using ::testing::Return;
constexpr absl::string_view kTestUuid = "00000000-0000-0000-0000-000000000000";
constexpr absl::string_view kTestServiceId = "test_service_id";
class MockBluetoothAdapter : public BluetoothAdapter {
public:
MOCK_METHOD(bool, IsValid, (), (const));
MOCK_METHOD(bool, SetStatus, (api::BluetoothAdapter::Status status),
(override));
MOCK_METHOD(bool, IsEnabled, (), (const, override));
MOCK_METHOD(api::BluetoothAdapter::Status, GetStatus, (), (const));
MOCK_METHOD(bool, SetName, (absl::string_view name), (override));
MOCK_METHOD(bool, SetName, (absl::string_view name, bool persist),
(override));
MOCK_METHOD(std::string, GetName, (), (const, override));
MOCK_METHOD(std::string, GetMacAddress, (), (const, override));
MOCK_METHOD(bool, SetScanMode, (api::BluetoothAdapter::ScanMode scan_mode),
(override));
MOCK_METHOD(api::BluetoothAdapter::ScanMode, GetScanMode, (),
(const, override));
MOCK_METHOD(int, GetNumSlots, (), (const));
MOCK_METHOD(api::ble_v2::BlePeripheral::UniqueId, GetUniqueId, (), (const));
MOCK_METHOD(void, SetBleV2Medium, (api::ble_v2::BleMedium * medium));
};
TEST(BleV2MediumTest, StartAdvertising) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
api::ble_v2::BleAdvertisementData advertising_data;
advertising_data.is_extended_advertisement = false;
advertising_data.service_data.insert(
{Uuid(kTestUuid), ByteArray("test_service_data")});
auto advertising_session = ble_v2_medium.StartAdvertising(
advertising_data,
{.tx_power_level = api::ble_v2::TxPowerLevel::kLow,
.is_connectable = true},
api::ble_v2::BleMedium::AdvertisingCallback{
.start_advertising_result = [](absl::Status) {},
});
EXPECT_TRUE(advertising_session != nullptr);
}
TEST(BleV2MediumTest, StopAdvertising) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
EXPECT_TRUE(ble_v2_medium.StopAdvertising());
}
TEST(BleV2MediumTest, StartScanning) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
auto scanning_session = ble_v2_medium.StartScanning(
Uuid(kTestUuid), api::ble_v2::TxPowerLevel::kLow,
api::ble_v2::BleMedium::ScanningCallback{
.start_scanning_result = [](absl::Status) {},
.advertisement_found_cb = [](api::ble_v2::BlePeripheral::UniqueId,
api::ble_v2::BleAdvertisementData) {},
});
EXPECT_TRUE(scanning_session != nullptr);
}
TEST(BleV2MediumTest, StopScanning) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
EXPECT_TRUE(ble_v2_medium.StopScanning());
}
TEST(BleV2MediumTest, StartGattServer) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
auto gatt_server = ble_v2_medium.StartGattServer({});
EXPECT_TRUE(gatt_server != nullptr);
}
TEST(BleV2MediumTest, ConnectToGattServer) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
auto gatt_client = ble_v2_medium.ConnectToGattServer(
/*peripheral_id=*/1234, api::ble_v2::TxPowerLevel::kLow, {});
EXPECT_TRUE(gatt_client == nullptr);
}
TEST(BleV2MediumTest, OpenServerSocket) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
auto server_socket =
ble_v2_medium.OpenServerSocket(std::string(kTestServiceId));
EXPECT_TRUE(server_socket != nullptr);
}
TEST(BleV2MediumTest, Connect) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
auto socket = ble_v2_medium.Connect(
std::string(kTestServiceId), api::ble_v2::TxPowerLevel::kLow,
/*remote_peripheral_id=*/1234, /*cancellation_flag=*/nullptr);
EXPECT_TRUE(socket == nullptr);
}
TEST(BleV2MediumTest, OpenL2capServerSocket) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
auto server_socket =
ble_v2_medium.OpenL2capServerSocket(std::string(kTestServiceId));
EXPECT_TRUE(server_socket == nullptr);
}
TEST(BleV2MediumTest, IsExtendedAdvertisementsAvailable) {
MockBluetoothAdapter mock_bluetooth_adapter;
EXPECT_CALL(mock_bluetooth_adapter, IsEnabled()).WillRepeatedly(Return(true));
BleV2Medium ble_v2_medium(mock_bluetooth_adapter);
EXPECT_FALSE(ble_v2_medium.IsExtendedAdvertisementsAvailable());
}
} // namespace
} // namespace g3
} // namespace nearby
@@ -194,7 +194,8 @@ std::unique_ptr<BleMedium> ImplementationPlatform::CreateBleMedium(
std::unique_ptr<api::ble_v2::BleMedium>
ImplementationPlatform::CreateBleV2Medium(api::BluetoothAdapter& adapter) {
return std::make_unique<g3::BleV2Medium>(adapter);
return std::make_unique<g3::BleV2Medium>(
dynamic_cast<g3::BluetoothAdapter&>(adapter));
}
std::unique_ptr<api::CredentialStorage>