Internal change

PiperOrigin-RevId: 359631402
This commit is contained in:
hai007
2021-02-25 15:44:53 -08:00
committed by Copybara-Service
parent e9c2d0a173
commit 970a101586
10 changed files with 174 additions and 43 deletions
+1
View File
@@ -52,6 +52,7 @@ cc_library(
"//location/nearby/mediums/proto:web_rtc_signaling_frames_cc_proto",
"//absl/container:flat_hash_map",
"//absl/container:flat_hash_set",
"//absl/functional:bind_front",
"//absl/numeric:int128",
"//absl/strings",
"//absl/time",
+48 -20
View File
@@ -27,6 +27,7 @@
#include "platform/public/logging.h"
#include "platform/public/mutex_lock.h"
#include "location/nearby/mediums/proto/web_rtc_signaling_frames.pb.h"
#include "absl/functional/bind_front.h"
#include "absl/strings/str_cat.h"
#include "absl/time/time.h"
#include "webrtc/api/jsep.h"
@@ -122,14 +123,9 @@ bool WebRtc::StartAcceptingConnections(const std::string& service_id,
// This registers ourselves w/ Tachyon, creating a room from the PeerId.
// This allows a remote device to message us over Tachyon.
auto signaling_message_callback = [this, service_id](ByteArray message) {
OffloadFromThread([this, service_id{std::move(service_id)},
message{std::move(message)}]() {
ProcessTachyonInboxMessage(service_id, message);
});
};
if (!info.signaling_messenger->StartReceivingMessages(
signaling_message_callback)) {
absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id),
absl::bind_front(&WebRtc::OnSignalingComplete, this, service_id))) {
info.signaling_messenger.reset();
return false;
}
@@ -270,14 +266,16 @@ WebRtcSocketWrapper WebRtc::AttemptToConnect(
// This registers ourselves w/ Tachyon, creating a room from the PeerId.
// This allows a remote device to message us over Tachyon.
auto signaling_message_callback = [this, service_id](ByteArray message) {
OffloadFromThread([this, service_id{std::move(service_id)},
message{std::move(message)}]() {
ProcessTachyonInboxMessage(service_id, message);
});
auto signaling_complete_callback = [this, &socket_future](bool success) {
if (!success) {
OffloadFromThread([&socket_future]() {
socket_future.SetException({Exception::kFailed});
});
}
};
if (!info.signaling_messenger->StartReceivingMessages(
signaling_message_callback)) {
absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id),
signaling_complete_callback)) {
NEARBY_LOG(INFO,
"Cannot connect to WebRTC peer %s because we failed to start "
"receiving messages over Tachyon.",
@@ -392,6 +390,37 @@ void WebRtc::ProcessLocalIceCandidate(
service_id.c_str());
}
void WebRtc::OnSignalingMessage(const std::string& service_id,
const ByteArray& message) {
OffloadFromThread([this, service_id, message]() {
ProcessTachyonInboxMessage(service_id, message);
});
}
void WebRtc::OnSignalingComplete(const std::string& service_id, bool success) {
NEARBY_LOG(INFO, "Signaling completed with status: %d.", success);
if (success) {
return;
}
OffloadFromThread([this, service_id]() {
MutexLock lock(&mutex_);
const auto& info_entry = accepting_connections_info_.find(service_id);
if (info_entry == accepting_connections_info_.end()) {
return;
}
if (info_entry->second.restart_accept_connections_count <
kRestartAcceptConnectionsLimit) {
++info_entry->second.restart_accept_connections_count;
} else {
return;
}
RestartTachyonReceiveMessages(service_id);
});
}
void WebRtc::ProcessTachyonInboxMessage(const std::string& service_id,
const ByteArray& message) {
MutexLock lock(&mutex_);
@@ -593,6 +622,10 @@ void WebRtc::ReceiveIceCandidates(
void WebRtc::ProcessRestartTachyonReceiveMessages(
const std::string& service_id) {
MutexLock lock(&mutex_);
RestartTachyonReceiveMessages(service_id);
}
void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) {
if (!IsAcceptingConnectionsLocked(service_id)) {
NEARBY_LOG(INFO,
"Skipping restart listening for tachyon inbox messages since we "
@@ -608,14 +641,9 @@ void WebRtc::ProcessRestartTachyonReceiveMessages(
info.signaling_messenger->StopReceivingMessages();
// Attempt to re-register.
auto signaling_message_callback = [this, service_id](ByteArray message) {
OffloadFromThread([this, service_id{std::move(service_id)},
message{std::move(message)}]() {
ProcessTachyonInboxMessage(service_id, message);
});
};
if (!info.signaling_messenger->StartReceivingMessages(
signaling_message_callback)) {
absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id),
absl::bind_front(&WebRtc::OnSignalingComplete, this, service_id))) {
NEARBY_LOG(WARNING,
"Failed to restart listening for tachyon inbox messages for "
"service %s since we failed to reach Tachyon.",
+20 -2
View File
@@ -15,6 +15,7 @@
#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_H_
#define CORE_INTERNAL_MEDIUMS_WEBRTC_H_
#include <cstddef>
#include <memory>
#include <string>
@@ -98,6 +99,9 @@ class WebRtc {
ABSL_LOCKS_EXCLUDED(mutex_);
private:
static constexpr int kConnectAttemptsLimit = 3;
static constexpr int kRestartAcceptConnectionsLimit = 3;
enum class Role {
kNone = 0,
kOfferer = 1,
@@ -121,6 +125,11 @@ class WebRtc {
// advertising. Non-null when listening for WebRTC connections as an
// offerer.
CancelableAlarm restart_tachyon_receive_messages_alarm;
// Tracks the number of times we've restarted receiving messages after a
// failure. We limit the number to prevent endless restarts if we are
// repeatedly unable to communicate with Tachyon.
int restart_accept_connections_count = 0;
};
struct ConnectionRequestInfo {
@@ -136,8 +145,6 @@ class WebRtc {
Future<WebRtcSocketWrapper> socket_future;
};
static constexpr int kConnectAttemptsLimit = 3;
// Attempt to initiates a WebRtc connection with peer device identified by
// |peer_id|.
// Runs on @MainThread.
@@ -152,6 +159,13 @@ class WebRtc {
bool IsAcceptingConnectionsLocked(const std::string& service_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Receives a message from the signaling messenger.
void OnSignalingMessage(const std::string& service_id,
const ByteArray& message);
// Decides whether to restart receiving messages.
void OnSignalingComplete(const std::string& service_id, bool success);
// Runs on |single_thread_executor_|.
void ProcessTachyonInboxMessage(const std::string& service_id,
const ByteArray& message)
@@ -223,6 +237,10 @@ class WebRtc {
void ProcessRestartTachyonReceiveMessages(const std::string& service_id)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
void RestartTachyonReceiveMessages(const std::string& service_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
void OffloadFromThread(Runnable runnable);
Mutex mutex_;
+36 -3
View File
@@ -158,9 +158,9 @@ TEST_F(WebRtcTest, StartAcceptingConnectionTwice) {
EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{}));
}
// Tests the flow when the device tries to connect but the data channel times
// out.
TEST_F(WebRtcTest, Connect_DataChannelTimeOut) {
// Tests the flow when the device tries to connect but there is no peer
// accepting connections at the given peer ID.
TEST_F(WebRtcTest, Connect_NoPeer) {
WebRtc webrtc;
PeerId peer_id("peer_id");
const std::string service_id("NearbySharing");
@@ -353,6 +353,39 @@ TEST_F(WebRtcTest, Connect_NullPeerConnection) {
EXPECT_FALSE(wrapper.IsValid());
}
// Tests the flow when the device calls StartAcceptingConnections and the
// receive messages stream fails.
TEST_F(WebRtcTest, ContinueAcceptingConnectionsOnComplete) {
using MockAcceptedCallback =
testing::MockFunction<void(WebRtcSocketWrapper socket)>;
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
WebRtc webrtc;
PeerId self_id("peer_id");
const std::string service_id("NearbySharing");
LocationHint location_hint;
ASSERT_TRUE(webrtc.IsAvailable());
ASSERT_TRUE(webrtc.StartAcceptingConnections(
service_id, self_id, location_hint,
{mock_accepted_callback_.AsStdFunction()}));
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
// Simulate a failure in receiving messages stream, WebRtc should restart
// accepting connections.
MediumEnvironment::Instance().SendWebRtcSignalingComplete(self_id.GetId(),
/*success=*/false);
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
// And a "success" message should not cause accepting connections to stop.
MediumEnvironment::Instance().SendWebRtcSignalingComplete(self_id.GetId(),
/*success=*/true);
EXPECT_TRUE(webrtc.IsAcceptingConnections(service_id));
webrtc.StopAcceptingConnections(service_id);
EXPECT_FALSE(webrtc.IsAcceptingConnections(service_id));
}
} // namespace
} // namespace mediums