mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 07:06:11 -04:00
Merge branch 'master' into release
Change-Id: I8a6cfe28093bf3d60dc91bcbc4e98e641764c4c0
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "absl/numeric/int128.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "smhasher/MurmurHash3.h"
|
||||
#include "smhasher/src/MurmurHash3.h"
|
||||
|
||||
namespace location {
|
||||
namespace nearby {
|
||||
|
||||
@@ -21,11 +21,13 @@
|
||||
#include "core_v2/internal/mediums/webrtc/signaling_frames.h"
|
||||
#include "platform_v2/base/byte_array.h"
|
||||
#include "platform_v2/base/listeners.h"
|
||||
#include "platform_v2/public/cancelable_alarm.h"
|
||||
#include "platform_v2/public/future.h"
|
||||
#include "platform_v2/public/logging.h"
|
||||
#include "platform_v2/public/mutex_lock.h"
|
||||
#include "location/nearby/mediums/proto/web_rtc_signaling_frames.pb.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "webrtc/api/jsep.h"
|
||||
|
||||
namespace location {
|
||||
@@ -36,19 +38,22 @@ namespace mediums {
|
||||
namespace {
|
||||
|
||||
// The maximum amount of time to wait to connect to a data channel via WebRTC.
|
||||
// TODO(himanshujaju): Should this be configurable per platform?
|
||||
constexpr absl::Duration kDataChannelTimeout = absl::Milliseconds(5000);
|
||||
|
||||
// Delay between restarting signaling messenger to receive messages.
|
||||
constexpr absl::Duration kRestartReceiveMessagesDuration = absl::Seconds(60);
|
||||
|
||||
} // namespace
|
||||
|
||||
WebRtc::WebRtc() = default;
|
||||
|
||||
WebRtc::~WebRtc() {
|
||||
// This ensures that all pending callbacks are run before we reset the medium
|
||||
// and we are not accepting new runnables.
|
||||
restart_receive_messages_executor_.Shutdown();
|
||||
single_thread_executor_.Shutdown();
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
bool WebRtc::IsAvailable() { return medium_.IsValid(); }
|
||||
@@ -84,6 +89,11 @@ bool WebRtc::StartAcceptingConnections(const PeerId& self_id,
|
||||
|
||||
if (!InitWebRtcFlow(Role::kOfferer, self_id)) return false;
|
||||
|
||||
restart_receive_messages_alarm_ = CancelableAlarm(
|
||||
"restart_receiving_messages_webrtc",
|
||||
std::bind(&WebRtc::RestartReceiveMessages, this),
|
||||
kRestartReceiveMessagesDuration, &restart_receive_messages_executor_);
|
||||
|
||||
SessionDescriptionWrapper offer = connection_flow_->CreateOffer();
|
||||
pending_local_offer_ = webrtc_frames::EncodeOffer(self_id, offer.GetSdp());
|
||||
if (!SetLocalSessionDescription(std::move(offer))) {
|
||||
@@ -103,23 +113,25 @@ bool WebRtc::StartAcceptingConnections(const PeerId& self_id,
|
||||
}
|
||||
|
||||
WebRtcSocketWrapper WebRtc::Connect(const PeerId& peer_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
if (!IsAvailable()) {
|
||||
Disconnect();
|
||||
return WebRtcSocketWrapper();
|
||||
}
|
||||
|
||||
if (role_ != Role::kNone) {
|
||||
NEARBY_LOG(WARNING,
|
||||
"Cannot connect with WebRtc because we are already acting as %d",
|
||||
role_);
|
||||
return WebRtcSocketWrapper();
|
||||
}
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
if (role_ != Role::kNone) {
|
||||
NEARBY_LOG(
|
||||
WARNING,
|
||||
"Cannot connect with WebRtc because we are already acting as %d",
|
||||
role_);
|
||||
return WebRtcSocketWrapper();
|
||||
}
|
||||
|
||||
peer_id_ = peer_id;
|
||||
if (!InitWebRtcFlow(Role::kAnswerer, PeerId::FromRandom())) {
|
||||
return WebRtcSocketWrapper();
|
||||
peer_id_ = peer_id;
|
||||
if (!InitWebRtcFlow(Role::kAnswerer, PeerId::FromRandom())) {
|
||||
return WebRtcSocketWrapper();
|
||||
}
|
||||
}
|
||||
|
||||
NEARBY_LOG(INFO, "Attempting to make a WebRTC connection to %s.",
|
||||
@@ -130,6 +142,9 @@ WebRtcSocketWrapper WebRtc::Connect(const PeerId& peer_id) {
|
||||
|
||||
// The two devices have discovered each other, hence we have a timeout for
|
||||
// establishing the transport channel.
|
||||
// NOTE - We should not hold |mutex_| while waiting for the data channel since
|
||||
// it would block incoming signaling messages from being processed, resulting
|
||||
// in a timeout in creating the socket.
|
||||
ExceptionOr<WebRtcSocketWrapper> result =
|
||||
socket_future.Get(kDataChannelTimeout);
|
||||
if (result.ok()) return result.result();
|
||||
@@ -200,7 +215,8 @@ WebRtcSocketWrapper WebRtc::CreateWebRtcSocketWrapper(
|
||||
}
|
||||
|
||||
auto socket = std::make_unique<WebRtcSocket>("WebRtcSocket", data_channel);
|
||||
socket->SetOnSocketClosedListener({std::bind(&WebRtc::Disconnect, this)});
|
||||
socket->SetOnSocketClosedListener(
|
||||
{[this]() { OffloadFromSignalingThread([this]() { Disconnect(); }); }});
|
||||
return WebRtcSocketWrapper(std::move(socket));
|
||||
}
|
||||
|
||||
@@ -231,7 +247,7 @@ bool WebRtc::InitWebRtcFlow(Role role, const PeerId& self_id) {
|
||||
if (!signaling_messenger_->IsValid() ||
|
||||
!signaling_messenger_->StartReceivingMessages(
|
||||
signaling_message_callback)) {
|
||||
Disconnect();
|
||||
DisconnectLocked();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -407,7 +423,7 @@ void WebRtc::SendAnswerToPeer() {
|
||||
|
||||
void WebRtc::LogAndDisconnect(const std::string& error_message) {
|
||||
NEARBY_LOG(WARNING, "Disconnecting WebRTC : %s", error_message.c_str());
|
||||
Disconnect();
|
||||
DisconnectLocked();
|
||||
}
|
||||
|
||||
void WebRtc::LogAndShutdownSignaling(const std::string& error_message) {
|
||||
@@ -422,6 +438,11 @@ void WebRtc::ShutdownSignaling() {
|
||||
pending_local_offer_ = ByteArray();
|
||||
pending_local_ice_candidates_.clear();
|
||||
|
||||
if (restart_receive_messages_alarm_.IsValid()) {
|
||||
restart_receive_messages_alarm_.Cancel();
|
||||
restart_receive_messages_alarm_ = CancelableAlarm();
|
||||
}
|
||||
|
||||
if (signaling_messenger_) {
|
||||
signaling_messenger_->StopReceivingMessages();
|
||||
signaling_messenger_.reset();
|
||||
@@ -431,6 +452,11 @@ void WebRtc::ShutdownSignaling() {
|
||||
}
|
||||
|
||||
void WebRtc::Disconnect() {
|
||||
MutexLock lock(&mutex_);
|
||||
DisconnectLocked();
|
||||
}
|
||||
|
||||
void WebRtc::DisconnectLocked() {
|
||||
ShutdownSignaling();
|
||||
ShutdownWebRtcSocket();
|
||||
ShutdownIceCandidateCollection();
|
||||
@@ -454,6 +480,34 @@ void WebRtc::OffloadFromSignalingThread(Runnable runnable) {
|
||||
single_thread_executor_.Execute(std::move(runnable));
|
||||
}
|
||||
|
||||
void WebRtc::RestartReceiveMessages() {
|
||||
if (!IsAcceptingConnections()) {
|
||||
NEARBY_LOG(INFO,
|
||||
"Skipping restart since we are not accepting connections.");
|
||||
return;
|
||||
}
|
||||
|
||||
NEARBY_LOG(INFO, "Restarting listening for receiving signaling messages.");
|
||||
{
|
||||
MutexLock lock(&mutex_);
|
||||
signaling_messenger_->StopReceivingMessages();
|
||||
|
||||
signaling_messenger_ = medium_.GetSignalingMessenger(self_id_.GetId());
|
||||
|
||||
auto signaling_message_callback = [this](ByteArray message) {
|
||||
OffloadFromSignalingThread([this, message{std::move(message)}]() {
|
||||
ProcessSignalingMessage(message);
|
||||
});
|
||||
};
|
||||
|
||||
if (!signaling_messenger_->IsValid() ||
|
||||
!signaling_messenger_->StartReceivingMessages(
|
||||
signaling_message_callback)) {
|
||||
DisconnectLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mediums
|
||||
} // namespace connections
|
||||
} // namespace nearby
|
||||
|
||||
@@ -24,9 +24,12 @@
|
||||
#include "core_v2/internal/mediums/webrtc/peer_id.h"
|
||||
#include "core_v2/internal/mediums/webrtc/webrtc_socket.h"
|
||||
#include "core_v2/internal/mediums/webrtc/webrtc_socket_wrapper.h"
|
||||
#include "platform_v2/public/cancelable_alarm.h"
|
||||
#include "platform_v2/public/scheduled_executor.h"
|
||||
#include "platform_v2/base/byte_array.h"
|
||||
#include "platform_v2/base/listeners.h"
|
||||
#include "platform_v2/base/runnable.h"
|
||||
#include "platform_v2/public/atomic_boolean.h"
|
||||
#include "platform_v2/public/future.h"
|
||||
#include "platform_v2/public/mutex.h"
|
||||
#include "platform_v2/public/single_thread_executor.h"
|
||||
@@ -126,8 +129,11 @@ class WebRtc {
|
||||
void LogAndDisconnect(const std::string& error_message)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
// Runs on @MainThread.
|
||||
void Disconnect() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Runs on @MainThread and |single_thread_executor_|.
|
||||
void Disconnect() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
void DisconnectLocked() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
|
||||
void LogAndShutdownSignaling(const std::string& error_message)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
|
||||
@@ -143,6 +149,9 @@ class WebRtc {
|
||||
|
||||
void OffloadFromSignalingThread(Runnable runnable);
|
||||
|
||||
// Runs on |restart_receive_messages_executor_|.
|
||||
void RestartReceiveMessages() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
Mutex mutex_;
|
||||
|
||||
Role role_ ABSL_GUARDED_BY(mutex_) = Role::kNone;
|
||||
@@ -159,6 +168,10 @@ class WebRtc {
|
||||
WebRtcSocketWrapper socket_ ABSL_GUARDED_BY(mutex_);
|
||||
|
||||
SingleThreadExecutor single_thread_executor_;
|
||||
|
||||
// Restarts the signaling messenger for receiving messages.
|
||||
ScheduledExecutor restart_receive_messages_executor_;
|
||||
CancelableAlarm restart_receive_messages_alarm_;
|
||||
};
|
||||
|
||||
} // namespace mediums
|
||||
|
||||
@@ -103,28 +103,139 @@ TEST(WebRtcTest, StartAndStopAcceptingConnections) {
|
||||
EXPECT_FALSE(webrtc.IsAcceptingConnections());
|
||||
}
|
||||
|
||||
// Tests the flow when the device calls StartAcceptingConnections() after
|
||||
// calling Connect() without disconnecting in between.
|
||||
TEST(WebRtcTest, Connect_ThenStartAcceptingConnections) {
|
||||
// TODO(himanshujaju) - Complete the test.
|
||||
}
|
||||
|
||||
// Tests the flow when the device tries to connect to two different peers
|
||||
// without disconnecting in between.
|
||||
TEST(WebRtcTest, ConnectTwice) {
|
||||
// TODO(himanshujaju) - Complete the test.
|
||||
WebRtc receiver, sender, device_c;
|
||||
WebRtcSocketWrapper receiver_socket, sender_socket;
|
||||
const PeerId self_id("self_id"), other_id("other_id");
|
||||
Future<bool> connected;
|
||||
ByteArray message("message xyz");
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
self_id,
|
||||
{[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
|
||||
using MockAcceptedCallback =
|
||||
testing::MockFunction<void(WebRtcSocketWrapper socket)>;
|
||||
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
|
||||
device_c.StartAcceptingConnections(other_id,
|
||||
{mock_accepted_callback_.AsStdFunction()});
|
||||
|
||||
sender_socket = sender.Connect(self_id);
|
||||
EXPECT_TRUE(sender_socket.IsValid());
|
||||
|
||||
ExceptionOr<bool> devices_connected = connected.Get();
|
||||
ASSERT_TRUE(devices_connected.ok());
|
||||
EXPECT_TRUE(devices_connected.result());
|
||||
|
||||
WebRtcSocketWrapper socket = sender.Connect(other_id);
|
||||
EXPECT_FALSE(socket.IsValid());
|
||||
|
||||
EXPECT_TRUE(receiver_socket.IsValid());
|
||||
EXPECT_TRUE(sender_socket.IsValid());
|
||||
|
||||
sender_socket.GetOutputStream().Write(message);
|
||||
ExceptionOr<ByteArray> received_msg =
|
||||
receiver_socket.GetInputStream().Read(/*size=*/32);
|
||||
ASSERT_TRUE(received_msg.ok());
|
||||
EXPECT_EQ(message, received_msg.result());
|
||||
|
||||
receiver_socket.Close();
|
||||
}
|
||||
|
||||
// Tests the flow when the two devices exchange SDP messages and connect to each
|
||||
// other but disconnect before being able to send/receive the actual data.
|
||||
TEST(WebRtcTest, ConnectBothDevicesAndAbort) {
|
||||
// TODO(himanshujaju) - Complete the test.
|
||||
WebRtc receiver, sender;
|
||||
WebRtcSocketWrapper receiver_socket, sender_socket;
|
||||
const PeerId self_id("self_id");
|
||||
Future<bool> connected;
|
||||
ByteArray message("message xyz");
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
self_id,
|
||||
{[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
|
||||
sender_socket = sender.Connect(self_id);
|
||||
EXPECT_TRUE(sender_socket.IsValid());
|
||||
|
||||
ExceptionOr<bool> devices_connected = connected.Get();
|
||||
ASSERT_TRUE(devices_connected.ok());
|
||||
EXPECT_TRUE(devices_connected.result());
|
||||
|
||||
receiver_socket.Close();
|
||||
}
|
||||
|
||||
// Tests the flow when the two devices exchange SDP messages and connect to each
|
||||
// other and the actual data is exchanged successfully between the devices.
|
||||
TEST(WebRtcTest, ConnectBothDevicesAndSendData) {
|
||||
// TODO(himanshujaju) - Complete the test.
|
||||
WebRtc receiver, sender;
|
||||
WebRtcSocketWrapper receiver_socket, sender_socket;
|
||||
const PeerId self_id("self_id");
|
||||
Future<bool> connected;
|
||||
ByteArray message("message");
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
self_id,
|
||||
{[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
|
||||
sender_socket = sender.Connect(self_id);
|
||||
EXPECT_TRUE(sender_socket.IsValid());
|
||||
|
||||
ExceptionOr<bool> devices_connected = connected.Get();
|
||||
ASSERT_TRUE(devices_connected.ok());
|
||||
EXPECT_TRUE(devices_connected.result());
|
||||
|
||||
sender_socket.GetOutputStream().Write(message);
|
||||
ExceptionOr<ByteArray> received_msg =
|
||||
receiver_socket.GetInputStream().Read(/*size=*/32);
|
||||
ASSERT_TRUE(received_msg.ok());
|
||||
EXPECT_EQ(message, received_msg.result());
|
||||
|
||||
receiver_socket.Close();
|
||||
}
|
||||
|
||||
// Tests the flow when the two devices exchange SDP messages and connect to each
|
||||
// other but the signaling channel is closed before sending the data.
|
||||
TEST(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) {
|
||||
WebRtc receiver, sender;
|
||||
WebRtcSocketWrapper receiver_socket, sender_socket;
|
||||
const PeerId self_id("self_id");
|
||||
Future<bool> connected;
|
||||
ByteArray message("message xyz");
|
||||
|
||||
receiver.StartAcceptingConnections(
|
||||
self_id,
|
||||
{[&receiver_socket, connected](WebRtcSocketWrapper wrapper) mutable {
|
||||
receiver_socket = wrapper;
|
||||
connected.Set(receiver_socket.IsValid());
|
||||
}});
|
||||
|
||||
sender_socket = sender.Connect(self_id);
|
||||
EXPECT_TRUE(sender_socket.IsValid());
|
||||
|
||||
ExceptionOr<bool> devices_connected = connected.Get();
|
||||
ASSERT_TRUE(devices_connected.ok());
|
||||
EXPECT_TRUE(devices_connected.result());
|
||||
|
||||
// Only shuts down signaling channel.
|
||||
receiver.StopAcceptingConnections();
|
||||
|
||||
sender_socket.GetOutputStream().Write(message);
|
||||
ExceptionOr<ByteArray> received_msg =
|
||||
receiver_socket.GetInputStream().Read(/*size=*/32);
|
||||
ASSERT_TRUE(received_msg.ok());
|
||||
EXPECT_EQ(message, received_msg.result());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -57,24 +57,28 @@ bool WifiLan::StartAdvertising(const std::string& service_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
NEARBY_LOG(INFO, "Turned on WifiLan advertising with service info name=%s",
|
||||
wifi_lan_service_info_name.c_str());
|
||||
NEARBY_LOGS(INFO) << "Turned on WifiLan advertising with service info name="
|
||||
<< wifi_lan_service_info_name
|
||||
<< ", service id=" << service_id;
|
||||
advertising_info_.service_id = service_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WifiLan::StopAdvertising(const std::string& service_id) {
|
||||
bool WifiLan::StopAdvertising(const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
if (!IsAdvertisingLocked()) {
|
||||
NEARBY_LOG(INFO, "Can't turn off WifiLan advertising; it is already off");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
medium_.StopAdvertising(advertising_info_.service_id);
|
||||
NEARBY_LOG(INFO, "Turned off WifiLan advertising with service id=%s",
|
||||
service_id.c_str());
|
||||
bool ret = medium_.StopAdvertising(advertising_info_.service_id);
|
||||
// Reset our bundle of advertising state to mark that we're no longer
|
||||
// advertising.
|
||||
advertising_info_.Clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WifiLan::IsAdvertising() {
|
||||
@@ -117,23 +121,28 @@ bool WifiLan::StartDiscovery(const std::string& service_id,
|
||||
return false;
|
||||
}
|
||||
|
||||
NEARBY_LOG(INFO, "Turned on WifiLan discovering with service id=%s",
|
||||
service_id.c_str());
|
||||
// Mark the fact that we're currently performing a WifiLan discovering.
|
||||
discovering_info_.service_id = service_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
void WifiLan::StopDiscovery(const std::string& service_id) {
|
||||
bool WifiLan::StopDiscovery(const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
if (!IsDiscoveringLocked(service_id)) {
|
||||
NEARBY_LOG(INFO,
|
||||
"Can't turn off WifiLan discovering because we never started "
|
||||
"discovering.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
medium_.StopDiscovery(service_id);
|
||||
NEARBY_LOG(INFO, "Turned off WifiLan discovering with service id=%s",
|
||||
service_id.c_str());
|
||||
bool ret = medium_.StopDiscovery(service_id);
|
||||
discovering_info_.Clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WifiLan::IsDiscovering(const std::string& service_id) {
|
||||
@@ -183,20 +192,22 @@ bool WifiLan::StartAcceptingConnections(const std::string& service_id,
|
||||
return true;
|
||||
}
|
||||
|
||||
void WifiLan::StopAcceptingConnections(const std::string& service_id) {
|
||||
bool WifiLan::StopAcceptingConnections(const std::string& service_id) {
|
||||
MutexLock lock(&mutex_);
|
||||
|
||||
if (!IsAcceptingConnectionsLocked(service_id)) {
|
||||
NEARBY_LOG(INFO,
|
||||
"Can't stop accepting WifiLan connections because it was never "
|
||||
"started.");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
medium_.StopAcceptingConnections(accepting_connections_info_.service_id);
|
||||
bool ret =
|
||||
medium_.StopAcceptingConnections(accepting_connections_info_.service_id);
|
||||
// Reset our bundle of accepting connections state to mark that we're no
|
||||
// longer accepting connections.
|
||||
accepting_connections_info_.Clear();
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool WifiLan::IsAcceptingConnections(const std::string& service_id) {
|
||||
|
||||
@@ -44,7 +44,7 @@ class WifiLan {
|
||||
|
||||
// Disables WifiLan advertising, and restores service info name to
|
||||
// what they were before the call to StartAdvertising().
|
||||
void StopAdvertising(const std::string& service_id)
|
||||
bool StopAdvertising(const std::string& service_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool IsAdvertising() ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
@@ -57,7 +57,7 @@ class WifiLan {
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Disables WifiLan discovery mode.
|
||||
void StopDiscovery(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
bool StopDiscovery(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool IsDiscovering(const std::string& service_id) ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
@@ -68,7 +68,7 @@ class WifiLan {
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
// Closes socket corresponding to a service id.
|
||||
void StopAcceptingConnections(const std::string& service_id)
|
||||
bool StopAcceptingConnections(const std::string& service_id)
|
||||
ABSL_LOCKS_EXCLUDED(mutex_);
|
||||
|
||||
bool IsAcceptingConnections(const std::string& service_id)
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <string>
|
||||
|
||||
#include "platform_v2/base/medium_environment.h"
|
||||
#include "platform_v2/public/count_down_latch.h"
|
||||
#include "platform_v2/public/logging.h"
|
||||
#include "platform_v2/public/wifi_lan.h"
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
@@ -26,11 +28,11 @@ namespace nearby {
|
||||
namespace connections {
|
||||
namespace {
|
||||
|
||||
constexpr absl::Duration kWaitDuration = absl::Milliseconds(1000);
|
||||
constexpr absl::string_view kServiceID{"com.google.location.nearby.apps.test"};
|
||||
constexpr absl::string_view kServiceInfoName{
|
||||
"Simulated WifiLan service encrypted string #1"};
|
||||
|
||||
// TODO(edwinwu): Continue writing more tests after medium_environment is done.
|
||||
class WifiLanTest : public ::testing::Test {
|
||||
protected:
|
||||
using DiscoveredServiceCallback = WifiLanMedium::DiscoveredServiceCallback;
|
||||
@@ -44,6 +46,8 @@ TEST_F(WifiLanTest, CanConstructValidObject) {
|
||||
env_.Start();
|
||||
WifiLan wifi_lan_a;
|
||||
WifiLan wifi_lan_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_name{kServiceInfoName};
|
||||
|
||||
EXPECT_TRUE(wifi_lan_a.IsAvailable());
|
||||
EXPECT_TRUE(wifi_lan_b.IsAvailable());
|
||||
@@ -52,9 +56,100 @@ TEST_F(WifiLanTest, CanConstructValidObject) {
|
||||
|
||||
TEST_F(WifiLanTest, CanStartAdvertising) {
|
||||
env_.Start();
|
||||
WifiLan wifi_lan;
|
||||
EXPECT_TRUE(wifi_lan.StartAdvertising(std::string(kServiceID),
|
||||
std::string(kServiceInfoName)));
|
||||
WifiLan wifi_lan_a;
|
||||
WifiLan wifi_lan_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_name{kServiceInfoName};
|
||||
CountDownLatch found_latch(1);
|
||||
|
||||
wifi_lan_b.StartDiscovery(
|
||||
service_id, DiscoveredServiceCallback{
|
||||
.service_discovered_cb =
|
||||
[&found_latch](WifiLanService& service,
|
||||
const std::string& service_id) {
|
||||
found_latch.CountDown();
|
||||
},
|
||||
});
|
||||
|
||||
EXPECT_TRUE(wifi_lan_a.StartAdvertising(service_id, service_name));
|
||||
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_a.StopAdvertising(service_id));
|
||||
EXPECT_TRUE(wifi_lan_b.StopDiscovery(service_id));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanTest, CanStartDiscovery) {
|
||||
env_.Start();
|
||||
WifiLan wifi_lan_a;
|
||||
WifiLan wifi_lan_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_name{kServiceInfoName};
|
||||
CountDownLatch accept_latch(1);
|
||||
CountDownLatch lost_latch(1);
|
||||
|
||||
wifi_lan_b.StartAdvertising(service_id, service_name);
|
||||
|
||||
EXPECT_TRUE(wifi_lan_a.StartDiscovery(
|
||||
service_id, {
|
||||
.service_discovered_cb =
|
||||
[&accept_latch](WifiLanService& service,
|
||||
const std::string& service_id) {
|
||||
accept_latch.CountDown();
|
||||
},
|
||||
.service_lost_cb =
|
||||
[&lost_latch](WifiLanService& service,
|
||||
const std::string& service_id) {
|
||||
lost_latch.CountDown();
|
||||
},
|
||||
}));
|
||||
EXPECT_TRUE(accept_latch.Await(kWaitDuration).result());
|
||||
wifi_lan_b.StopAdvertising(service_id);
|
||||
EXPECT_TRUE(lost_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(wifi_lan_a.StopDiscovery(service_id));
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
TEST_F(WifiLanTest, CanStartAcceptingConnectionsAndConnect) {
|
||||
env_.Start();
|
||||
WifiLan wifi_lan_a;
|
||||
WifiLan wifi_lan_b;
|
||||
std::string service_id(kServiceID);
|
||||
std::string service_name{kServiceInfoName};
|
||||
CountDownLatch found_latch(1);
|
||||
CountDownLatch accept_latch(1);
|
||||
|
||||
wifi_lan_a.StartAdvertising(service_id, service_name);
|
||||
wifi_lan_a.StartAcceptingConnections(
|
||||
service_id,
|
||||
{
|
||||
.accepted_cb = [&accept_latch](
|
||||
WifiLanSocket socket,
|
||||
const std::string&) { accept_latch.CountDown(); },
|
||||
});
|
||||
WifiLanService discovered_service;
|
||||
wifi_lan_b.StartDiscovery(
|
||||
service_id,
|
||||
{
|
||||
.service_discovered_cb =
|
||||
[&found_latch, &discovered_service](
|
||||
WifiLanService& service, const std::string& service_id) {
|
||||
discovered_service = service;
|
||||
NEARBY_LOG(INFO, "Discovered service=%p [impl=%p]", &service,
|
||||
&service.GetImpl());
|
||||
found_latch.CountDown();
|
||||
},
|
||||
});
|
||||
|
||||
EXPECT_TRUE(found_latch.Await(kWaitDuration).result());
|
||||
ASSERT_TRUE(discovered_service.IsValid());
|
||||
|
||||
WifiLanSocket socket =
|
||||
wifi_lan_b.Connect(discovered_service, service_id);
|
||||
|
||||
EXPECT_TRUE(accept_latch.Await(kWaitDuration).result());
|
||||
EXPECT_TRUE(socket.IsValid());
|
||||
wifi_lan_b.StopDiscovery(service_id);
|
||||
wifi_lan_a.StopAdvertising(service_id);
|
||||
env_.Stop();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
// Copyright 2020 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 "core_v2/internal/offline_service_controller.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
#ifndef CORE_V2_INTERNAL_OFFLINE_SERVICE_CONTROLLER_H_
|
||||
#define CORE_V2_INTERNAL_OFFLINE_SERVICE_CONTROLLER_H_
|
||||
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
// Copyright 2020 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 "core_v2/internal/offline_service_controller.h"
|
||||
|
||||
#include "core_v2/internal/offline_simulation_user.h"
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
// Copyright 2020 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 "core_v2/internal/offline_simulation_user.h"
|
||||
|
||||
#include "core_v2/listeners.h"
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
// Copyright 2020 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.
|
||||
|
||||
#ifndef CORE_V2_INTERNAL_OFFLINE_SIMULATION_USER_H_
|
||||
#define CORE_V2_INTERNAL_OFFLINE_SIMULATION_USER_H_
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ proto::connections::Medium P2pClusterPcpHandler::StartWifiLanAdvertising(
|
||||
service_id.c_str());
|
||||
if (!wifi_lan_medium_.StartAcceptingConnections(
|
||||
service_id, {.accepted_cb = [this, client, local_endpoint_name](
|
||||
WifiLanSocket& socket,
|
||||
WifiLanSocket socket,
|
||||
const std::string& service_id) {
|
||||
if (!socket.IsValid()) {
|
||||
NEARBY_LOG(ERROR, "Invalid socket in accept callback: name=%s",
|
||||
|
||||
Reference in New Issue
Block a user