Merge branch 'google3' to master, roll forward up to cl/355302206.

This commit is contained in:
hai007
2021-02-04 13:34:05 -08:00
41 changed files with 1194 additions and 472 deletions
+1
View File
@@ -67,6 +67,7 @@ cc_library(
deps = [
"//proto/connections:offline_wire_formats_portable_proto",
"//platform/base",
"//platform/base:cancellation_flag",
"//absl/strings",
"//absl/types:optional",
"//webrtc/api:libjingle_peerconnection_api",
+4 -2
View File
@@ -17,6 +17,7 @@
#include "platform/api/bluetooth_classic.h"
#include "platform/base/byte_array.h"
#include "platform/base/cancellation_flag.h"
#include "platform/base/input_stream.h"
#include "platform/base/output_stream.h"
@@ -112,8 +113,9 @@ class BleMedium {
// Connects to a BLE peripheral.
// On success, returns a new BleSocket.
// On error, returns nullptr.
virtual std::unique_ptr<BleSocket> Connect(BlePeripheral& peripheral,
const std::string& service_id) = 0;
virtual std::unique_ptr<BleSocket> Connect(
BlePeripheral& peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) = 0;
};
} // namespace api
+3 -1
View File
@@ -19,6 +19,7 @@
#include <string>
#include "platform/base/byte_array.h"
#include "platform/base/cancellation_flag.h"
#include "platform/base/exception.h"
#include "platform/base/input_stream.h"
#include "platform/base/listeners.h"
@@ -136,7 +137,8 @@ class BluetoothClassicMedium {
// On success, returns a new BluetoothSocket.
// On error, returns nullptr.
virtual std::unique_ptr<BluetoothSocket> ConnectToService(
BluetoothDevice& remote_device, const std::string& service_uuid) = 0;
BluetoothDevice& remote_device, const std::string& service_uuid,
CancellationFlag* cancellation_flag) = 0;
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord
//
+3 -1
View File
@@ -18,6 +18,7 @@
#include <string>
#include "platform/base/byte_array.h"
#include "platform/base/cancellation_flag.h"
#include "platform/base/input_stream.h"
#include "platform/base/listeners.h"
#include "platform/base/nsd_service_info.h"
@@ -113,7 +114,8 @@ class WifiLanMedium {
// On success, returns a new WifiLanSocket.
// On error, returns nullptr.
virtual std::unique_ptr<WifiLanSocket> Connect(
WifiLanService& wifi_lan_service, const std::string& service_id) = 0;
WifiLanService& wifi_lan_service, const std::string& service_id,
CancellationFlag* cancellation_flag) = 0;
virtual WifiLanService* GetRemoteService(const std::string& ip_address,
int port) = 0;
+3
View File
@@ -176,7 +176,10 @@ cc_test(
"cancellation_flag_test.cc",
],
deps = [
":base",
":cancellation_flag",
":test_util",
"//platform/impl/g3", # build_cleaner: keep
"//testing/base/public:gunit_main",
],
)
+12
View File
@@ -1,5 +1,7 @@
#include "platform/base/cancellation_flag.h"
#include "platform/base/feature_flags.h"
namespace location {
namespace nearby {
@@ -15,6 +17,11 @@ CancellationFlag::CancellationFlag(bool cancelled) {
void CancellationFlag::Cancel() {
absl::MutexLock lock(mutex_.get());
// Return immediately as no-op if feature flag is not enabled.
if (!FeatureFlags::GetInstance().GetFlags().enable_cancellation_flag) {
return;
}
if (cancelled_) {
// Someone already cancelled. Return immediately.
return;
@@ -25,6 +32,11 @@ void CancellationFlag::Cancel() {
bool CancellationFlag::Cancelled() const {
absl::MutexLock lock(mutex_.get());
// Return falsea as no-op if feature flag is not enabled.
if (!FeatureFlags::GetInstance().GetFlags().enable_cancellation_flag) {
return false;
}
return cancelled_;
}
+55 -4
View File
@@ -1,20 +1,71 @@
#include "platform/base/cancellation_flag.h"
#include "platform/base/feature_flags.h"
#include "platform/base/medium_environment.h"
#include "gtest/gtest.h"
namespace location {
namespace nearby {
namespace {
TEST(CancellationFlagTest, InitialValueIsFalse) {
using FeatureFlags = FeatureFlags::Flags;
constexpr FeatureFlags kTestCases[] = {
FeatureFlags{
.enable_cancellation_flag = true,
},
FeatureFlags{
.enable_cancellation_flag = false,
},
};
class CancellationFlagTest : public ::testing::TestWithParam<FeatureFlags> {
protected:
void SetUp() override {
feature_flags_ = GetParam();
env_.SetFeatureFlags(feature_flags_);
}
FeatureFlags feature_flags_;
MediumEnvironment& env_{MediumEnvironment::Instance()};
};
TEST_P(CancellationFlagTest, InitialValueIsFalse) {
CancellationFlag flag;
// No matter FeatureFlag is enabled or not, Cancelled is always false.
EXPECT_FALSE(flag.Cancelled());
}
TEST(CancellationFlagTest, CanCancel) {
CancellationFlag flag;
flag.Cancel();
TEST_P(CancellationFlagTest, InitialValueAsTrue) {
CancellationFlag flag{true};
// If FeatureFlag is disabled, Cancelled is false as no-op.
if (!feature_flags_.enable_cancellation_flag) {
EXPECT_FALSE(flag.Cancelled());
return;
}
EXPECT_TRUE(flag.Cancelled());
}
TEST_P(CancellationFlagTest, CanCancel) {
CancellationFlag flag;
flag.Cancel();
// If FeatureFlag is disabled, return as no-op immediately and
// Cancelled is always false.
if (!feature_flags_.enable_cancellation_flag) {
EXPECT_FALSE(flag.Cancelled());
return;
}
EXPECT_TRUE(flag.Cancelled());
}
INSTANTIATE_TEST_SUITE_P(ParametrisedCancellationFlagTest, CancellationFlagTest,
::testing::ValuesIn(kTestCases));
} // namespace
} // namespace nearby
} // namespace location
+1 -1
View File
@@ -12,7 +12,7 @@ class FeatureFlags {
public:
// Holds for all the feature flags.
struct Flags {
bool enable_cancellation_flags = false;
bool enable_cancellation_flag = false;
bool resume_before_disconnect = true;
};
+6 -5
View File
@@ -7,18 +7,19 @@ namespace location {
namespace nearby {
namespace {
FeatureFlags::Flags kTestFeatureFlags{.enable_cancellation_flags = true};
constexpr FeatureFlags::Flags kTestFeatureFlags{.enable_cancellation_flag =
true};
TEST(FeatureFlagsTest, ToStringWorks) {
TEST(FeatureFlagsTest, ToSetFeatureWorks) {
const FeatureFlags& features = FeatureFlags::GetInstance();
EXPECT_FALSE(features.GetFlags().enable_cancellation_flags);
EXPECT_FALSE(features.GetFlags().enable_cancellation_flag);
MediumEnvironment& medium_environment = MediumEnvironment::Instance();
medium_environment.SetFeatureFlags(kTestFeatureFlags);
EXPECT_TRUE(features.GetFlags().enable_cancellation_flags);
EXPECT_TRUE(features.GetFlags().enable_cancellation_flag);
const FeatureFlags& another_features_ref = FeatureFlags::GetInstance();
EXPECT_TRUE(another_features_ref.GetFlags().enable_cancellation_flags);
EXPECT_TRUE(another_features_ref.GetFlags().enable_cancellation_flag);
}
} // namespace
+1
View File
@@ -69,6 +69,7 @@ cc_library(
":types",
"//platform/api:comm",
"//platform/base",
"//platform/base:cancellation_flag",
"//platform/base:logging",
"//platform/base:test_util",
"//absl/base:core_headers",
+9 -1
View File
@@ -317,7 +317,8 @@ bool BleMedium::StopAcceptingConnections(const std::string& service_id) {
}
std::unique_ptr<api::BleSocket> BleMedium::Connect(
api::BlePeripheral& remote_peripheral, const std::string& service_id) {
api::BlePeripheral& remote_peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) {
NEARBY_LOG(INFO,
"G3 Ble Connect [self]: medium=%p, adapter=%p, peripheral=%p, "
"service_id=%s",
@@ -346,6 +347,13 @@ std::unique_ptr<api::BleSocket> BleMedium::Connect(
}
}
if (cancellation_flag->Cancelled()) {
NEARBY_LOGS(ERROR) << "G3 BLE Connect: Has been cancelled: "
"service_id="
<< service_id;
return {};
}
BlePeripheral peripheral = static_cast<BlePeripheral&>(remote_peripheral);
auto socket = std::make_unique<BleSocket>(&peripheral);
// Finally, Request to connect to this socket.
+3 -2
View File
@@ -183,8 +183,9 @@ class BleMedium : public api::BleMedium {
// On success, returns a new BleSocket.
// On error, returns nullptr.
std::unique_ptr<api::BleSocket> Connect(
api::BlePeripheral& remote_peripheral,
const std::string& service_id) override ABSL_LOCKS_EXCLUDED(mutex_);
api::BlePeripheral& remote_peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag) override
ABSL_LOCKS_EXCLUDED(mutex_);
BluetoothAdapter& GetAdapter() { return *adapter_; }
+9 -1
View File
@@ -199,7 +199,8 @@ bool BluetoothClassicMedium::StopDiscovery() {
}
std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
api::BluetoothDevice& remote_device, const std::string& service_uuid) {
api::BluetoothDevice& remote_device, const std::string& service_uuid,
CancellationFlag* cancellation_flag) {
NEARBY_LOG(INFO,
"G3 ConnectToService [self]: medium=%p, adapter=%p, device=%p",
this, &GetAdapter(), &GetAdapter().GetDevice());
@@ -227,6 +228,13 @@ std::unique_ptr<api::BluetoothSocket> BluetoothClassicMedium::ConnectToService(
}
}
if (cancellation_flag->Cancelled()) {
NEARBY_LOGS(ERROR) << "G3 Bluetooth Connect: Has been cancelled: "
"service_uuid="
<< service_uuid;
return {};
}
auto socket = std::make_unique<BluetoothSocket>(&GetAdapter());
// Finally, Request to connect to this socket.
if (!server_socket->Connect(*socket)) {
+3 -2
View File
@@ -201,8 +201,9 @@ class BluetoothClassicMedium : public api::BluetoothClassicMedium {
// On success, returns a new BluetoothSocket.
// On error, returns nullptr.
std::unique_ptr<api::BluetoothSocket> ConnectToService(
api::BluetoothDevice& remote_device,
const std::string& service_uuid) override ABSL_LOCKS_EXCLUDED(mutex_);
api::BluetoothDevice& remote_device, const std::string& service_uuid,
CancellationFlag* cancellation_flag) override
ABSL_LOCKS_EXCLUDED(mutex_);
BluetoothAdapter& GetAdapter() { return *adapter_; }
+9 -2
View File
@@ -317,8 +317,8 @@ bool WifiLanMedium::StopAcceptingConnections(const std::string& service_id) {
}
std::unique_ptr<api::WifiLanSocket> WifiLanMedium::Connect(
api::WifiLanService& remote_wifi_lan_service,
const std::string& service_id) {
api::WifiLanService& remote_wifi_lan_service, const std::string& service_id,
CancellationFlag* cancellation_flag) {
NEARBY_LOG(
INFO,
"G3 WifiLan Connect: medium=%p, wifi_lan_service=%p, "
@@ -354,6 +354,13 @@ std::unique_ptr<api::WifiLanSocket> WifiLanMedium::Connect(
}
}
if (cancellation_flag->Cancelled()) {
NEARBY_LOGS(INFO) << "G3 WifiLan Connect: Has been cancelled: "
"service_id="
<< service_id;
return {};
}
WifiLanService wifi_lan_service =
static_cast<WifiLanService&>(remote_wifi_lan_service);
auto socket = std::make_unique<WifiLanSocket>(&wifi_lan_service);
+3 -1
View File
@@ -204,7 +204,9 @@ class WifiLanMedium : public api::WifiLanMedium {
// On error, returns nullptr.
std::unique_ptr<api::WifiLanSocket> Connect(
api::WifiLanService& remote_wifi_lan_service,
const std::string& service_id) override ABSL_LOCKS_EXCLUDED(mutex_);
const std::string& service_id,
CancellationFlag* cancellation_flag) override
ABSL_LOCKS_EXCLUDED(mutex_);
api::WifiLanService* GetRemoteService(const std::string& ip_address,
int port) override;
+1
View File
@@ -82,6 +82,7 @@ cc_library(
"//platform/api:comm",
"//platform/api:platform",
"//platform/base",
"//platform/base:cancellation_flag",
"//absl/container:flat_hash_map",
"//absl/strings",
"//webrtc/api:libjingle_peerconnection_api",
+4 -2
View File
@@ -127,13 +127,15 @@ bool BleMedium::StopAcceptingConnections(const std::string& service_id) {
}
BleSocket BleMedium::Connect(BlePeripheral& peripheral,
const std::string& service_id) {
const std::string& service_id,
CancellationFlag* cancellation_flag) {
{
MutexLock lock(&mutex_);
NEARBY_LOG(INFO, "BleMedium::Connect: peripheral=%p [impl=%p]", &peripheral,
&peripheral.GetImpl());
}
return BleSocket(impl_->Connect(peripheral.GetImpl(), service_id));
return BleSocket(
impl_->Connect(peripheral.GetImpl(), service_id, cancellation_flag));
}
} // namespace nearby
+3 -1
View File
@@ -18,6 +18,7 @@
#include "platform/api/ble.h"
#include "platform/api/platform.h"
#include "platform/base/byte_array.h"
#include "platform/base/cancellation_flag.h"
#include "platform/base/input_stream.h"
#include "platform/base/output_stream.h"
#include "platform/public/bluetooth_adapter.h"
@@ -137,7 +138,8 @@ class BleMedium final {
// Returns a new BleSocket. On Success, BleSocket::IsValid()
// returns true.
BleSocket Connect(BlePeripheral& peripheral, const std::string& service_id);
BleSocket Connect(BlePeripheral& peripheral, const std::string& service_id,
CancellationFlag* cancellation_flag);
bool IsValid() const { return impl_ != nullptr; }
+145 -60
View File
@@ -26,12 +26,23 @@ namespace location {
namespace nearby {
namespace {
using FeatureFlags = FeatureFlags::Flags;
constexpr FeatureFlags kTestCases[] = {
FeatureFlags{
.enable_cancellation_flag = true,
},
FeatureFlags{
.enable_cancellation_flag = false,
},
};
constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"};
constexpr absl::string_view kAdvertisementString{"\x0a\x0b\x0c\x0d"};
constexpr absl::string_view kFastAdvertisementServiceUuid{"\xf3\xfe"};
class BleMediumTest : public ::testing::Test {
class BleMediumTest : public ::testing::TestWithParam<FeatureFlags> {
protected:
using DiscoveredPeripheralCallback = BleMedium::DiscoveredPeripheralCallback;
using AcceptedConnectionCallback = BleMedium::AcceptedConnectionCallback;
@@ -41,6 +52,139 @@ class BleMediumTest : public ::testing::Test {
MediumEnvironment& env_{MediumEnvironment::Instance()};
};
TEST_P(BleMediumTest, CanStartAcceptingConnectionsAndConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
BlePeripheral* discovered_peripheral = nullptr;
ble_a.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch, &discovered_peripheral](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
NEARBY_LOG(
INFO,
"Peripheral discovered: %s, %p, fast advertisement: %d",
peripheral.GetName().c_str(), &peripheral,
fast_advertisement);
discovered_peripheral = &peripheral;
found_latch.CountDown();
},
});
ble_b.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
ble_b.StartAcceptingConnections(
service_id,
AcceptedConnectionCallback{
.accepted_cb = [&accepted_latch](BleSocket socket,
const std::string& service_id) {
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
&socket, service_id.c_str());
accepted_latch.CountDown();
}});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
BleSocket socket_a;
EXPECT_FALSE(socket_a.IsValid());
{
SingleThreadExecutor client_executor;
client_executor.Execute(
[&ble_a, &socket_a, discovered_peripheral, &service_id]() {
CancellationFlag flag;
socket_a = ble_a.Connect(*discovered_peripheral, service_id, &flag);
});
}
EXPECT_TRUE(accepted_latch.Await(kWaitDuration).result());
EXPECT_TRUE(socket_a.IsValid());
ble_b.StopAdvertising(service_id);
ble_a.StopScanning(service_id);
env_.Stop();
}
TEST_P(BleMediumTest, CanCancelConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
BlePeripheral* discovered_peripheral = nullptr;
ble_a.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch, &discovered_peripheral](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
NEARBY_LOG(
INFO,
"Peripheral discovered: %s, %p, fast advertisement: %d",
peripheral.GetName().c_str(), &peripheral,
fast_advertisement);
discovered_peripheral = &peripheral;
found_latch.CountDown();
},
});
ble_b.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
ble_b.StartAcceptingConnections(
service_id,
AcceptedConnectionCallback{
.accepted_cb = [&accepted_latch](BleSocket socket,
const std::string& service_id) {
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
&socket, service_id.c_str());
accepted_latch.CountDown();
}});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
BleSocket socket_a;
EXPECT_FALSE(socket_a.IsValid());
{
SingleThreadExecutor client_executor;
client_executor.Execute(
[&ble_a, &socket_a, discovered_peripheral, &service_id]() {
CancellationFlag flag(true);
socket_a = ble_a.Connect(*discovered_peripheral, service_id, &flag);
});
}
// If FeatureFlag is disabled, Cancelled is false as no-op.
if (!feature_flags.enable_cancellation_flag) {
EXPECT_TRUE(accepted_latch.Await(kWaitDuration).result());
EXPECT_TRUE(socket_a.IsValid());
} else {
EXPECT_FALSE(accepted_latch.Await(kWaitDuration).result());
EXPECT_FALSE(socket_a.IsValid());
}
ble_b.StopAdvertising(service_id);
ble_a.StopScanning(service_id);
env_.Stop();
}
INSTANTIATE_TEST_SUITE_P(ParametrisedBleMediumTest, BleMediumTest,
::testing::ValuesIn(kTestCases));
TEST_F(BleMediumTest, ConstructorDestructorWorks) {
env_.Start();
BluetoothAdapter adapter_a_;
@@ -156,65 +300,6 @@ TEST_F(BleMediumTest, CanStopDiscovery) {
env_.Stop();
}
TEST_F(BleMediumTest, CanStartAcceptingConnectionsAndConnect) {
env_.Start();
BluetoothAdapter adapter_a_;
BluetoothAdapter adapter_b_;
BleMedium ble_a{adapter_a_};
BleMedium ble_b{adapter_b_};
std::string service_id(kServiceID);
ByteArray advertisement_bytes{std::string(kAdvertisementString)};
std::string fast_advertisement_service_uuid(kFastAdvertisementServiceUuid);
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
BlePeripheral* discovered_peripheral = nullptr;
ble_a.StartScanning(
service_id, fast_advertisement_service_uuid,
DiscoveredPeripheralCallback{
.peripheral_discovered_cb =
[&found_latch, &discovered_peripheral](
BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement) {
NEARBY_LOG(
INFO,
"Peripheral discovered: %s, %p, fast advertisement: %d",
peripheral.GetName().c_str(), &peripheral,
fast_advertisement);
discovered_peripheral = &peripheral;
found_latch.CountDown();
},
});
ble_b.StartAdvertising(service_id, advertisement_bytes,
fast_advertisement_service_uuid);
ble_b.StartAcceptingConnections(
service_id,
AcceptedConnectionCallback{
.accepted_cb = [&accepted_latch](BleSocket socket,
const std::string& service_id) {
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
&socket, service_id.c_str());
accepted_latch.CountDown();
}});
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
BleSocket socket_a;
EXPECT_FALSE(socket_a.IsValid());
{
SingleThreadExecutor client_executor;
client_executor.Execute(
[&ble_a, &socket_a, discovered_peripheral, &service_id]() {
socket_a = ble_a.Connect(*discovered_peripheral, service_id);
});
}
EXPECT_TRUE(accepted_latch.Await(kWaitDuration).result());
EXPECT_TRUE(socket_a.IsValid());
ble_b.StopAdvertising(service_id);
ble_a.StopScanning(service_id);
env_.Stop();
}
} // namespace
} // namespace nearby
} // namespace location
+4 -3
View File
@@ -23,12 +23,13 @@ namespace nearby {
BluetoothClassicMedium::~BluetoothClassicMedium() { StopDiscovery(); }
BluetoothSocket BluetoothClassicMedium::ConnectToService(
BluetoothDevice& remote_device, const std::string& service_uuid) {
BluetoothDevice& remote_device, const std::string& service_uuid,
CancellationFlag* cancellation_flag) {
NEARBY_LOG(INFO,
"BluetoothClassicMedium::ConnectToService: device=%p [impl=%p]",
&remote_device, &remote_device.GetImpl());
return BluetoothSocket(
impl_->ConnectToService(remote_device.GetImpl(), service_uuid));
return BluetoothSocket(impl_->ConnectToService(
remote_device.GetImpl(), service_uuid, cancellation_flag));
}
bool BluetoothClassicMedium::StartDiscovery(DiscoveryCallback callback) {
+3 -1
View File
@@ -21,6 +21,7 @@
#include "platform/api/bluetooth_classic.h"
#include "platform/api/platform.h"
#include "platform/base/byte_array.h"
#include "platform/base/cancellation_flag.h"
#include "platform/base/exception.h"
#include "platform/base/input_stream.h"
#include "platform/base/listeners.h"
@@ -179,7 +180,8 @@ class BluetoothClassicMedium final {
// Returns a new BluetoothSocket. On Success, BluetoothSocket::IsValid()
// returns true.
BluetoothSocket ConnectToService(BluetoothDevice& remote_device,
const std::string& service_uuid);
const std::string& service_uuid,
CancellationFlag* cancellation_flag);
// https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#listenUsingInsecureRfcommWithServiceRecord
//
+121 -46
View File
@@ -29,7 +29,19 @@ namespace location {
namespace nearby {
namespace {
class BluetoothClassicMediumTest : public ::testing::Test {
using FeatureFlags = FeatureFlags::Flags;
constexpr FeatureFlags kTestCases[] = {
FeatureFlags{
.enable_cancellation_flag = true,
},
FeatureFlags{
.enable_cancellation_flag = false,
},
};
class BluetoothClassicMediumTest
: public ::testing::TestWithParam<FeatureFlags> {
protected:
using DiscoveryCallback = BluetoothClassicMedium::DiscoveryCallback;
BluetoothClassicMediumTest() {
@@ -66,6 +78,114 @@ class BluetoothClassicMediumTest : public ::testing::Test {
std::unique_ptr<BluetoothClassicMedium> bt_b_;
};
TEST_P(BluetoothClassicMediumTest, CanConnectToService) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
CountDownLatch found_latch(1);
BluetoothDevice* discovered_device = nullptr;
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch, &discovered_device](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
},
});
adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
EXPECT_EQ(adapter_b_->GetScanMode(),
BluetoothAdapter::ScanMode::kConnectableDiscoverable);
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
std::string service_name{"service"};
std::string service_uuid("service-uuid");
BluetoothServerSocket server_socket =
bt_b_->ListenForService(service_name, service_uuid);
EXPECT_TRUE(server_socket.IsValid());
BluetoothSocket socket_a;
BluetoothSocket socket_b;
EXPECT_FALSE(socket_a.IsValid());
EXPECT_FALSE(socket_b.IsValid());
{
SingleThreadExecutor server_executor;
SingleThreadExecutor client_executor;
client_executor.Execute(
[this, &socket_a, discovered_device, &service_uuid, &server_socket]() {
CancellationFlag flag;
socket_a =
bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
if (!socket_a.IsValid()) server_socket.Close();
});
server_executor.Execute([&socket_b, &server_socket]() {
socket_b = server_socket.Accept();
if (!socket_b.IsValid()) server_socket.Close();
});
}
EXPECT_TRUE(socket_a.IsValid());
EXPECT_TRUE(socket_b.IsValid());
server_socket.Close();
}
TEST_P(BluetoothClassicMediumTest, CanCancelConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
CountDownLatch found_latch(1);
BluetoothDevice* discovered_device = nullptr;
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch, &discovered_device](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
},
});
adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
EXPECT_EQ(adapter_b_->GetScanMode(),
BluetoothAdapter::ScanMode::kConnectableDiscoverable);
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
std::string service_name{"service"};
std::string service_uuid("service-uuid");
BluetoothServerSocket server_socket =
bt_b_->ListenForService(service_name, service_uuid);
EXPECT_TRUE(server_socket.IsValid());
BluetoothSocket socket_a;
BluetoothSocket socket_b;
EXPECT_FALSE(socket_a.IsValid());
EXPECT_FALSE(socket_b.IsValid());
{
SingleThreadExecutor server_executor;
SingleThreadExecutor client_executor;
client_executor.Execute(
[this, &socket_a, discovered_device, &service_uuid, &server_socket]() {
CancellationFlag flag(true);
socket_a =
bt_a_->ConnectToService(*discovered_device, service_uuid, &flag);
if (!socket_a.IsValid()) server_socket.Close();
});
server_executor.Execute([&socket_b, &server_socket]() {
socket_b = server_socket.Accept();
if (!socket_b.IsValid()) server_socket.Close();
});
}
// If FeatureFlag is disabled, Cancelled is false as no-op.
if (!feature_flags.enable_cancellation_flag) {
EXPECT_TRUE(socket_a.IsValid());
EXPECT_TRUE(socket_b.IsValid());
} else {
EXPECT_FALSE(socket_a.IsValid());
EXPECT_FALSE(socket_b.IsValid());
}
server_socket.Close();
}
INSTANTIATE_TEST_SUITE_P(ParametrisedBluetoothClassicMediumTest,
BluetoothClassicMediumTest,
::testing::ValuesIn(kTestCases));
TEST_F(BluetoothClassicMediumTest, ConstructorDestructorWorks) {
// Make sure we can create functional adapters.
ASSERT_TRUE(adapter_a_->IsValid());
@@ -163,51 +283,6 @@ TEST_F(BluetoothClassicMediumTest, CanListenForService) {
server_socket.Close();
}
TEST_F(BluetoothClassicMediumTest, CanConnectToService) {
adapter_a_->SetScanMode(BluetoothAdapter::ScanMode::kConnectable);
CountDownLatch found_latch(1);
BluetoothDevice* discovered_device = nullptr;
bt_a_->StartDiscovery(DiscoveryCallback{
.device_discovered_cb =
[this, &found_latch, &discovered_device](BluetoothDevice& device) {
NEARBY_LOG(INFO, "Device discovered: %s", device.GetName().c_str());
EXPECT_EQ(device.GetName(), adapter_b_->GetName());
discovered_device = &device;
found_latch.CountDown();
},
});
adapter_b_->SetScanMode(BluetoothAdapter::ScanMode::kConnectableDiscoverable);
EXPECT_EQ(adapter_b_->GetScanMode(),
BluetoothAdapter::ScanMode::kConnectableDiscoverable);
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
std::string service_name{"service"};
std::string service_uuid("service-uuid");
BluetoothServerSocket server_socket =
bt_b_->ListenForService(service_name, service_uuid);
EXPECT_TRUE(server_socket.IsValid());
BluetoothSocket socket_a;
BluetoothSocket socket_b;
EXPECT_FALSE(socket_a.IsValid());
EXPECT_FALSE(socket_b.IsValid());
{
SingleThreadExecutor server_executor;
SingleThreadExecutor client_executor;
client_executor.Execute(
[this, &socket_a, discovered_device, &service_uuid, &server_socket]() {
socket_a = bt_a_->ConnectToService(*discovered_device, service_uuid);
if (!socket_a.IsValid()) server_socket.Close();
});
server_executor.Execute(
[&socket_b, &server_socket]() {
socket_b = server_socket.Accept();
if (!socket_b.IsValid()) server_socket.Close();
});
}
EXPECT_TRUE(socket_a.IsValid());
EXPECT_TRUE(socket_b.IsValid());
server_socket.Close();
}
} // namespace
} // namespace nearby
} // namespace location
+4 -2
View File
@@ -136,13 +136,15 @@ bool WifiLanMedium::StopAcceptingConnections(const std::string& service_id) {
}
WifiLanSocket WifiLanMedium::Connect(WifiLanService& wifi_lan_service,
const std::string& service_id) {
const std::string& service_id,
CancellationFlag* cancellation_flag) {
NEARBY_LOG(
INFO,
"WifiLanMedium::Connect: service=%p [impl=%p, service_info_name=%s]",
&wifi_lan_service, &wifi_lan_service.GetImpl(),
wifi_lan_service.GetServiceInfo().GetServiceInfoName().c_str());
return WifiLanSocket(impl_->Connect(wifi_lan_service.GetImpl(), service_id));
return WifiLanSocket(impl_->Connect(wifi_lan_service.GetImpl(), service_id,
cancellation_flag));
}
WifiLanService WifiLanMedium::GetRemoteService(const std::string& ip_address,
+3 -1
View File
@@ -18,6 +18,7 @@
#include "platform/api/platform.h"
#include "platform/api/wifi_lan.h"
#include "platform/base/byte_array.h"
#include "platform/base/cancellation_flag.h"
#include "platform/base/input_stream.h"
#include "platform/base/nsd_service_info.h"
#include "platform/base/output_stream.h"
@@ -151,7 +152,8 @@ class WifiLanMedium final {
// Returns a new WifiLanSocket. On Success, WifiLanSocket::IsValid()
// returns true.
WifiLanSocket Connect(WifiLanService& wifi_lan_service,
const std::string& service_id);
const std::string& service_id,
CancellationFlag* cancellation_flag);
bool IsValid() const { return impl_ != nullptr; }
+148 -60
View File
@@ -27,12 +27,23 @@ namespace location {
namespace nearby {
namespace {
using FeatureFlags = FeatureFlags::Flags;
constexpr FeatureFlags kTestCases[] = {
FeatureFlags{
.enable_cancellation_flag = true,
},
FeatureFlags{
.enable_cancellation_flag = false,
},
};
constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"};
constexpr absl::string_view kServiceInfoName{"Simulated service info name"};
constexpr absl::string_view kEndpointName{"Simulated endpoint name"};
constexpr absl::string_view kEndpointInfoKey{"n"};
class WifiLanMediumTest : public ::testing::Test {
class WifiLanMediumTest : public ::testing::TestWithParam<FeatureFlags> {
protected:
using DiscoveredServiceCallback = WifiLanMedium::DiscoveredServiceCallback;
using AcceptedConnectionCallback = WifiLanMedium::AcceptedConnectionCallback;
@@ -42,6 +53,142 @@ class WifiLanMediumTest : public ::testing::Test {
MediumEnvironment& env_{MediumEnvironment::Instance()};
};
TEST_P(WifiLanMediumTest, CanStartAcceptingConnectionsAndConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
WifiLanMedium wifi_a;
WifiLanMedium wifi_b;
std::string service_id(kServiceID);
std::string service_info_name{kServiceInfoName};
std::string endpoint_info_name{kEndpointName};
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
WifiLanService* discovered_service = nullptr;
wifi_a.StartDiscovery(
service_id,
DiscoveredServiceCallback{
.service_discovered_cb =
[&found_latch, &discovered_service](
WifiLanService& service, const std::string& service_id) {
NEARBY_LOG(
INFO, "Service discovered: %s, %p",
service.GetServiceInfo().GetServiceInfoName().c_str(),
&service);
discovered_service = &service;
found_latch.CountDown();
},
});
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceInfoName(service_info_name);
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
endpoint_info_name);
wifi_b.StartAdvertising(service_id, nsd_service_info);
wifi_b.StartAcceptingConnections(
service_id,
AcceptedConnectionCallback{
.accepted_cb = [&accepted_latch](WifiLanSocket socket,
const std::string& service_id) {
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
&socket, service_id.c_str());
accepted_latch.CountDown();
}});
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
WifiLanSocket socket_a;
EXPECT_FALSE(socket_a.IsValid());
{
SingleThreadExecutor client_executor;
client_executor.Execute(
[&wifi_a, &socket_a, discovered_service, &service_id]() {
CancellationFlag flag;
socket_a = wifi_a.Connect(*discovered_service, service_id, &flag);
});
}
EXPECT_TRUE(accepted_latch.Await(absl::Milliseconds(1000)).result());
EXPECT_TRUE(socket_a.IsValid());
wifi_b.StopAcceptingConnections(service_id);
wifi_b.StopAdvertising(service_id);
wifi_a.StopDiscovery(service_id);
env_.Stop();
}
TEST_P(WifiLanMediumTest, CanCancelConnect) {
FeatureFlags feature_flags = GetParam();
env_.SetFeatureFlags(feature_flags);
env_.Start();
WifiLanMedium wifi_a;
WifiLanMedium wifi_b;
std::string service_id(kServiceID);
std::string service_info_name{kServiceInfoName};
std::string endpoint_info_name{kEndpointName};
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
WifiLanService* discovered_service = nullptr;
wifi_a.StartDiscovery(
service_id,
DiscoveredServiceCallback{
.service_discovered_cb =
[&found_latch, &discovered_service](
WifiLanService& service, const std::string& service_id) {
NEARBY_LOG(
INFO, "Service discovered: %s, %p",
service.GetServiceInfo().GetServiceInfoName().c_str(),
&service);
discovered_service = &service;
found_latch.CountDown();
},
});
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceInfoName(service_info_name);
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
endpoint_info_name);
wifi_b.StartAdvertising(service_id, nsd_service_info);
wifi_b.StartAcceptingConnections(
service_id,
AcceptedConnectionCallback{
.accepted_cb = [&accepted_latch](WifiLanSocket socket,
const std::string& service_id) {
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
&socket, service_id.c_str());
accepted_latch.CountDown();
}});
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
WifiLanSocket socket_a;
EXPECT_FALSE(socket_a.IsValid());
{
SingleThreadExecutor client_executor;
client_executor.Execute(
[&wifi_a, &socket_a, discovered_service, &service_id]() {
// Make it as Cancelled.
CancellationFlag flag(true);
socket_a = wifi_a.Connect(*discovered_service, service_id, &flag);
});
}
// If FeatureFlag is disabled, Cancelled is false as no-op.
if (!feature_flags.enable_cancellation_flag) {
EXPECT_TRUE(accepted_latch.Await(absl::Milliseconds(1000)).result());
EXPECT_TRUE(socket_a.IsValid());
} else {
EXPECT_FALSE(accepted_latch.Await(absl::Milliseconds(1000)).result());
EXPECT_FALSE(socket_a.IsValid());
}
wifi_b.StopAcceptingConnections(service_id);
wifi_b.StopAdvertising(service_id);
wifi_a.StopDiscovery(service_id);
env_.Stop();
}
INSTANTIATE_TEST_SUITE_P(ParametrisedWifiLanMediumTest, WifiLanMediumTest,
::testing::ValuesIn(kTestCases));
TEST_F(WifiLanMediumTest, ConstructorDestructorWorks) {
env_.Start();
WifiLanMedium wifi_a;
@@ -158,65 +305,6 @@ TEST_F(WifiLanMediumTest, CanStopDiscovery) {
env_.Stop();
}
TEST_F(WifiLanMediumTest, CanStartAcceptingConnectionsAndConnect) {
env_.Start();
WifiLanMedium wifi_a;
WifiLanMedium wifi_b;
std::string service_id(kServiceID);
std::string service_info_name{kServiceInfoName};
std::string endpoint_info_name{kEndpointName};
CountDownLatch found_latch(1);
CountDownLatch accepted_latch(1);
WifiLanService* discovered_service = nullptr;
wifi_a.StartDiscovery(
service_id,
DiscoveredServiceCallback{
.service_discovered_cb =
[&found_latch, &discovered_service](
WifiLanService& service, const std::string& service_id) {
NEARBY_LOG(
INFO, "Service discovered: %s, %p",
service.GetServiceInfo().GetServiceInfoName().c_str(),
&service);
discovered_service = &service;
found_latch.CountDown();
},
});
NsdServiceInfo nsd_service_info;
nsd_service_info.SetServiceInfoName(service_info_name);
nsd_service_info.SetTxtRecord(std::string(kEndpointInfoKey),
endpoint_info_name);
wifi_b.StartAdvertising(service_id, nsd_service_info);
wifi_b.StartAcceptingConnections(
service_id,
AcceptedConnectionCallback{
.accepted_cb = [&accepted_latch](WifiLanSocket socket,
const std::string& service_id) {
NEARBY_LOG(INFO, "Connection accepted: socket=%p, service_id=%s",
&socket, service_id.c_str());
accepted_latch.CountDown();
}});
EXPECT_TRUE(found_latch.Await(absl::Milliseconds(1000)).result());
WifiLanSocket socket_a;
EXPECT_FALSE(socket_a.IsValid());
{
SingleThreadExecutor client_executor;
client_executor.Execute(
[&wifi_a, &socket_a, discovered_service, &service_id]() {
socket_a = wifi_a.Connect(*discovered_service, service_id);
});
}
EXPECT_TRUE(accepted_latch.Await(absl::Milliseconds(1000)).result());
EXPECT_TRUE(socket_a.IsValid());
wifi_b.StopAcceptingConnections(service_id);
wifi_b.StopAdvertising(service_id);
wifi_a.StopDiscovery(service_id);
env_.Stop();
}
} // namespace
} // namespace nearby
} // namespace location