Remove the need for WebRtc stub

PiperOrigin-RevId: 917974575
This commit is contained in:
Nick Bourdakos
2026-05-19 12:46:45 -07:00
committed by Copybara-Service
parent 269af7126e
commit 2a09838b61
12 changed files with 456 additions and 473 deletions
+1
View File
@@ -155,6 +155,7 @@ cc_library(
"//connections/implementation/flags:connections_flags",
"//connections/implementation/mediums",
"//connections/implementation/mediums:utils",
"//connections/implementation/mediums:webrtc",
"//connections/implementation/mediums:webrtc_peer_id",
"//connections/implementation/mediums:webrtc_socket",
"//connections/implementation/mediums/advertisements:dct_advertisement",
+25 -15
View File
@@ -25,8 +25,6 @@ cc_library(
"bluetooth_classic.cc",
"bluetooth_radio.cc",
"mediums.cc",
"webrtc.cc",
"webrtc_stub.cc",
"wifi_direct.cc",
"wifi_hotspot.cc",
"wifi_lan.cc",
@@ -37,21 +35,22 @@ cc_library(
"bluetooth_classic.h",
"bluetooth_radio.h",
"mediums.h",
"webrtc.h",
"webrtc_stub.h",
"wifi.h",
"wifi_direct.h",
"wifi_hotspot.h",
"wifi_lan.h",
],
copts = ["-DNO_WEBRTC"],
local_defines = select({
"//:webrtc_enabled": [],
"//conditions:default": ["NO_WEBRTC"],
}),
visibility = [
"//connections/implementation:__subpackages__",
],
deps = [
":utils",
":webrtc_peer_id",
":webrtc_socket",
":webrtc",
"//connections:core_types",
"//connections/implementation:types",
"//connections/implementation/flags:connections_flags",
@@ -59,8 +58,6 @@ cc_library(
"//connections/implementation/mediums/ble:ble_advertisement_header",
"//connections/implementation/mediums/ble:ble_socket",
"//connections/implementation/mediums/ble:bloom_filter",
"//connections/implementation/mediums/webrtc",
"//connections/implementation/proto:offline_wire_formats_cc_proto",
"//internal/flags:nearby_flags",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
@@ -72,21 +69,22 @@ cc_library(
"//internal/platform/flags:platform_flags",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:platform",
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
# "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep
# "//third_party/webrtc/files/stable/webrtc/api:jsep",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:btree",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/functional:bind_front",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
],
] + select({
"//:webrtc_enabled": [
"//connections/implementation/mediums/webrtc:webrtc_impl",
],
"//conditions:default": [],
}),
)
cc_library(
@@ -144,6 +142,20 @@ cc_library(
],
)
cc_library(
name = "webrtc",
hdrs = ["webrtc.h"],
visibility = ["//connections/implementation:__subpackages__"],
deps = [
":webrtc_peer_id",
":webrtc_socket",
"//connections/implementation/proto:offline_wire_formats_cc_proto",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
"@com_google_absl//absl/functional:any_invocable",
],
)
cc_test(
name = "core_internal_mediums_test",
size = "small",
@@ -191,7 +203,6 @@ cc_test(
size = "small",
srcs = [
"webrtc_peer_id_test.cc",
"webrtc_test.cc",
],
shard_count = 16,
tags = [
@@ -199,7 +210,6 @@ cc_test(
"requires-net:external",
],
deps = [
":mediums",
":webrtc_peer_id",
":webrtc_socket",
"//internal/platform:base",
+14 -1
View File
@@ -14,10 +14,15 @@
#include "connections/implementation/mediums/mediums.h"
#include <memory>
#include "connections/implementation/mediums/awdl.h"
#include "connections/implementation/mediums/ble.h"
#include "connections/implementation/mediums/bluetooth_classic.h"
#include "connections/implementation/mediums/bluetooth_radio.h"
#ifndef NO_WEBRTC
#include "connections/implementation/mediums/webrtc/webrtc_impl.h"
#endif
#include "connections/implementation/mediums/webrtc.h"
#include "connections/implementation/mediums/wifi.h"
#include "connections/implementation/mediums/wifi_direct.h"
@@ -27,6 +32,14 @@
namespace nearby {
namespace connections {
Mediums::Mediums() {
#ifndef NO_WEBRTC
webrtc_ = std::make_unique<mediums::WebRtcImpl>();
#else
webrtc_ = std::make_unique<mediums::WebRtc>();
#endif
}
BluetoothRadio& Mediums::GetBluetoothRadio() { return bluetooth_radio_; }
BluetoothClassic& Mediums::GetBluetoothClassic() { return bluetooth_classic_; }
@@ -41,7 +54,7 @@ WifiHotspot& Mediums::GetWifiHotspot() { return wifi_hotspot_; }
WifiDirect& Mediums::GetWifiDirect() { return wifi_direct_; }
mediums::WebRtc& Mediums::GetWebRtc() { return webrtc_; }
mediums::WebRtc& Mediums::GetWebRtc() { return *webrtc_; }
Awdl& Mediums::GetAwdl() { return awdl_; }
+4 -6
View File
@@ -15,15 +15,13 @@
#ifndef CORE_INTERNAL_MEDIUMS_MEDIUMS_H_
#define CORE_INTERNAL_MEDIUMS_MEDIUMS_H_
#include <memory>
#include "connections/implementation/mediums/awdl.h"
#include "connections/implementation/mediums/ble.h"
#include "connections/implementation/mediums/bluetooth_classic.h"
#include "connections/implementation/mediums/bluetooth_radio.h"
#ifdef NO_WEBRTC
#include "connections/implementation/mediums/webrtc_stub.h"
#else
#include "connections/implementation/mediums/webrtc.h"
#endif
#include "connections/implementation/mediums/wifi.h"
#include "connections/implementation/mediums/wifi_direct.h"
#include "connections/implementation/mediums/wifi_hotspot.h"
@@ -35,7 +33,7 @@ namespace connections {
// Facilitates convenient and reliable usage of various wireless mediums.
class Mediums {
public:
Mediums() = default;
Mediums();
~Mediums() = default;
// Returns a handle to the Bluetooth radio.
@@ -81,7 +79,7 @@ class Mediums {
WifiLan wifi_lan_;
WifiHotspot wifi_hotspot_;
WifiDirect wifi_direct_;
mediums::WebRtc webrtc_;
std::unique_ptr<mediums::WebRtc> webrtc_;
Awdl awdl_;
};
+20 -208
View File
@@ -15,262 +15,74 @@
#ifndef CORE_INTERNAL_MEDIUMS_WEBRTC_H_
#define CORE_INTERNAL_MEDIUMS_WEBRTC_H_
#ifndef NO_WEBRTC
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "connections/implementation/mediums/webrtc/connection_flow.h"
#include "connections/implementation/mediums/webrtc/session_description_wrapper.h"
#include "connections/implementation/mediums/webrtc_peer_id.h"
#include "connections/implementation/mediums/webrtc_socket.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancelable_alarm.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/expected.h"
#include "internal/platform/future.h"
#include "internal/platform/mutex.h"
#include "internal/platform/runnable.h"
#include "internal/platform/scheduled_executor.h"
#include "internal/platform/webrtc.h"
#include "proto/mediums/web_rtc_signaling_frames.pb.h"
#include "webrtc/api/jsep.h"
namespace nearby {
namespace connections {
namespace mediums {
// Entry point for connecting a data channel between two devices via WebRtc.
// A non-working base implementation for connecting a data channel between two
// devices via WebRtc.
class WebRtc {
public:
// Callback that is invoked when a new connection is accepted.
using AcceptedConnectionCallback = absl::AnyInvocable<void(
const std::string& service_id, std::shared_ptr<WebRtcSocket> socket)>;
WebRtc();
~WebRtc();
virtual ~WebRtc() = default;
// Gets the default two-letter country code associated with current locale.
// For example, en_US locale resolves to "US".
std::string GetDefaultCountryCode();
virtual std::string GetDefaultCountryCode() { return ""; }
// Returns if WebRtc is available as a medium for nearby to transport data.
// Runs on @MainThread.
bool IsAvailable();
virtual bool IsAvailable() { return false; }
// Returns if the device is accepting connection with specific service id.
// Runs on @MainThread.
bool IsAcceptingConnections(const std::string& service_id)
ABSL_LOCKS_EXCLUDED(mutex_);
virtual bool IsAcceptingConnections(const std::string& service_id) {
return false;
}
// Prepares the device to accept incoming WebRtc connections. Returns a
// boolean value indicating if the device has started accepting connections.
// Runs on @MainThread.
bool StartAcceptingConnections(
virtual bool StartAcceptingConnections(
const std::string& service_id, const WebrtcPeerId& self_peer_id,
const location::nearby::connections::LocationHint& location_hint,
AcceptedConnectionCallback callback, bool non_cellular)
ABSL_LOCKS_EXCLUDED(mutex_);
AcceptedConnectionCallback callback, bool non_cellular) {
return false;
}
// Try to stop (accepting) the specific connection with provided service id.
// Runs on @MainThread
void StopAcceptingConnections(const std::string& service_id)
ABSL_LOCKS_EXCLUDED(mutex_);
virtual void StopAcceptingConnections(const std::string& service_id) {}
// Initiates a WebRtc connection with peer device identified by |peer_id|
// with internal retry for maximum attempts of kConnectAttemptsLimit.
// Runs on @MainThread.
ErrorOr<std::shared_ptr<WebRtcSocket>> Connect(
virtual ErrorOr<std::shared_ptr<WebRtcSocket>> Connect(
const std::string& service_id, const WebrtcPeerId& peer_id,
const location::nearby::connections::LocationHint& location_hint,
CancellationFlag* cancellation_flag, bool non_cellular)
ABSL_LOCKS_EXCLUDED(mutex_);
CancellationFlag* cancellation_flag, bool non_cellular) {
return {Error(location::nearby::proto::connections::OperationResultCode::
DETAIL_UNKNOWN)};
}
bool IsUsingCellular() ABSL_LOCKS_EXCLUDED(mutex_);
protected:
// Use for unit tests only to inject a WebRtcMedium.
explicit WebRtc(std::unique_ptr<WebRtcMedium> medium);
// Used in unit tests to determine how many calls to `AttemptToConnect`
// occured during a call to `Connect`, per service id.
std::map<std::string, int> service_id_to_connect_attempts_count_map_;
private:
static constexpr int kConnectAttemptsLimit = 3;
static constexpr int kRestartAcceptConnectionsLimit = 3;
enum class Role {
kNone = 0,
kOfferer = 1,
kAnswerer = 2,
};
struct AcceptingConnectionsInfo {
// The self_peer_id is generated from the BT/WiFi advertisements and allows
// the scanner to message us over Tachyon.
WebrtcPeerId self_peer_id;
// The registered callback. When there's an incoming connection, this
// callback is notified.
AcceptedConnectionCallback accepted_connection_callback;
// Allows us to communicate with the Tachyon web server.
std::unique_ptr<WebRtcSignalingMessenger> signaling_messenger;
// Restarts the tachyon inbox receives messages streaming rpc if the
// streaming rpc times out. The streaming rpc times out after 60s while
// advertising. Non-null when listening for WebRTC connections as an
// offerer.
std::unique_ptr<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 {
// The self_peer_id is randomly generated and allows the advertiser to
// message us over Tachyon.
WebrtcPeerId self_peer_id;
// Allows us to communicate with the Tachyon web server.
std::unique_ptr<WebRtcSignalingMessenger> signaling_messenger;
// The pending DataChannel future. Our client will be blocked on this while
// they wait for us to set up the channel over Tachyon.
Future<std::shared_ptr<WebRtcSocket>> socket_future;
};
// Attempt to initiates a WebRtc connection with peer device identified by
// |peer_id|.
// Runs on @MainThread.
ErrorOr<std::shared_ptr<WebRtcSocket>> AttemptToConnect(
const std::string& service_id, const WebrtcPeerId& peer_id,
const location::nearby::connections::LocationHint& location_hint,
CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_);
// Returns if the device is accepting connection with specific service id.
// Runs on @MainThread.
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)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
void SendOffer(const std::string& service_id,
const WebrtcPeerId& remote_peer_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void ReceiveOffer(const WebrtcPeerId& remote_peer_id,
SessionDescriptionWrapper offer)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void SendAnswer(const WebrtcPeerId& remote_peer_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void ReceiveAnswer(const WebrtcPeerId& remote_peer_id,
SessionDescriptionWrapper answer)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void ReceiveIceCandidates(
const WebrtcPeerId& remote_peer_id,
std::vector<std::unique_ptr<webrtc::IceCandidate>> ice_candidates)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
std::unique_ptr<ConnectionFlow> CreateConnectionFlow(
const std::string& service_id, const WebrtcPeerId& remote_peer_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
std::unique_ptr<ConnectionFlow> GetConnectionFlow(
const WebrtcPeerId& remote_peer_id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void ProcessDataChannelOpen(const std::string& service_id,
const WebrtcPeerId& remote_peer_id,
std::shared_ptr<WebRtcSocket> socket_wrapper)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
void ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
void ProcessLocalIceCandidate(
const std::string& service_id, const WebrtcPeerId& remote_peer_id,
const location::nearby::mediums::IceCandidate ice_candidate)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
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_);
// Runs on |single_thread_executor_|.
void AdapterTypeChangedHandler(webrtc::AdapterType adapter_type)
ABSL_LOCKS_EXCLUDED(mutex_);
void OffloadFromThread(const std::string& name, Runnable runnable);
Mutex mutex_;
std::unique_ptr<WebRtcMedium> medium_;
// The single thread we throw the potentially blocking work on to.
ScheduledExecutor single_thread_executor_;
// A map of ServiceID -> State for all services that are listening for
// incoming connections.
absl::flat_hash_map<std::string, AcceptingConnectionsInfo>
accepting_connections_info_ ABSL_GUARDED_BY(mutex_);
// A map of a remote PeerId -> State for pending connection requests. As
// messages from Tachyon come in, this lets us look up the connection request
// info to handle the interaction.
absl::flat_hash_map<std::string, ConnectionRequestInfo>
requesting_connections_info_ ABSL_GUARDED_BY(mutex_);
// A map of a remote PeerId -> ConnectionFlow. For each connection, we create
// a unique ConnectionFlow.
absl::flat_hash_map<std::string, std::unique_ptr<ConnectionFlow>>
connection_flows_ ABSL_GUARDED_BY(mutex_);
bool is_using_cellular_ ABSL_GUARDED_BY(mutex_) = true;
virtual bool IsUsingCellular() { return false; }
};
} // namespace mediums
} // namespace connections
} // namespace nearby
#endif
#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_H_
+66 -18
View File
@@ -18,38 +18,37 @@ licenses(["notice"])
cc_library(
name = "webrtc",
srcs = [
"connection_flow.cc",
"signaling_frames.cc",
],
hdrs = [
"connection_flow.h",
"data_channel_listener.h",
"local_ice_candidate_listener.h",
"session_description_wrapper.h",
"signaling_frames.h",
],
copts = [
"-DCORE_ADAPTER_DLL",
"-DNO_WEBRTC",
],
visibility = [
"//connections/implementation:__subpackages__",
],
copts = ["-DNO_WEBRTC"],
deps = [
":webrtc_socket_impl",
"//connections:core_types",
"//connections/implementation/mediums:webrtc_peer_id",
"//connections/implementation/mediums:webrtc_socket",
# "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep
# "//third_party/webrtc/files/stable/webrtc/api:jsep",
# "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface",
"@com_google_absl//absl/functional:any_invocable",
],
)
cc_library(
name = "connection_flow",
srcs = ["connection_flow.cc"],
hdrs = ["connection_flow.h"],
deps = [
":webrtc",
":webrtc_socket_impl",
"//connections/implementation/mediums:webrtc_socket",
"//internal/platform:base",
"//internal/platform:comm",
"//internal/platform:logging",
"//internal/platform:types",
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
# "//third_party/webrtc/files/stable/webrtc/api:create_peerconnection_factory", # buildcleaner: keep
# "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface",
# "//third_party/webrtc/files/stable/webrtc/api:jsep",
# "//third_party/webrtc/files/stable/webrtc/api:peer_connection_interface",
# "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/memory",
@@ -57,6 +56,18 @@ cc_library(
],
)
cc_library(
name = "signaling_frames",
srcs = ["signaling_frames.cc"],
hdrs = ["signaling_frames.h"],
deps = [
"//connections/implementation/mediums:webrtc_peer_id",
"//internal/platform:base",
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
# "//third_party/webrtc/files/stable/webrtc/api:libjingle_peerconnection_api",
],
)
cc_library(
name = "webrtc_socket_impl",
srcs = ["webrtc_socket_impl.cc"],
@@ -76,28 +87,65 @@ cc_library(
],
)
cc_library(
name = "webrtc_impl",
srcs = ["webrtc_impl.cc"],
hdrs = ["webrtc_impl.h"],
visibility = [
"//connections/implementation:__subpackages__",
],
deps = [
":connection_flow",
":signaling_frames",
":webrtc",
"//connections/implementation/mediums:webrtc",
"//connections/implementation/mediums:webrtc_peer_id",
"//connections/implementation/mediums:webrtc_socket",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
"//internal/platform:comm",
"//internal/platform:logging",
"//internal/platform:types",
"//proto/mediums:web_rtc_signaling_frames_cc_proto",
# "//third_party/webrtc/files/stable/webrtc/api:jsep",
"//third_party/webrtc/files/stable/webrtc/rtc_base:network_constants",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/functional:bind_front",
"@com_google_absl//absl/time",
],
)
cc_test(
name = "webrtc_test",
timeout = "short",
srcs = [
"connection_flow_test.cc",
"signaling_frames_test.cc",
"webrtc_impl_test.cc",
"webrtc_socket_impl_test.cc",
],
shard_count = 16,
tags = [
"notsan", # NOTE(b/139734036): known data race in usrsctplib.
"requires-net:external",
],
deps = [
":connection_flow",
":signaling_frames",
":webrtc",
":webrtc_impl",
":webrtc_socket_impl",
"//connections/implementation/mediums:webrtc_peer_id",
"//connections/implementation/mediums:webrtc_socket",
"//internal/platform:base",
"//internal/platform:cancellation_flag",
"//internal/platform:comm",
"//internal/platform:test_util",
"//internal/platform:types",
"//internal/platform/implementation/g3", # buildcleaner: keep
"//internal/test",
# "//third_party/webrtc/files/stable/webrtc/api:data_channel_interface",
# "//third_party/webrtc/files/stable/webrtc/api:jsep",
# "//third_party/webrtc/files/stable/webrtc/api:scoped_refptr",
@@ -14,7 +14,7 @@
#ifndef NO_WEBRTC
#include "connections/implementation/mediums/webrtc.h"
#include "connections/implementation/mediums/webrtc/webrtc_impl.h"
#include <functional>
#include <memory>
@@ -43,6 +43,7 @@
#include "internal/platform/runnable.h"
#include "internal/platform/webrtc.h"
#include "webrtc/api/jsep.h"
#include "webrtc/rtc_base/network_constants.h"
namespace nearby {
namespace connections {
@@ -60,12 +61,12 @@ constexpr absl::Duration kRestartReceiveMessagesDuration = absl::Seconds(60);
} // namespace
WebRtc::WebRtc() : WebRtc(std::make_unique<WebRtcMedium>()) {}
WebRtcImpl::WebRtcImpl() : WebRtcImpl(std::make_unique<WebRtcMedium>()) {}
WebRtc::WebRtc(std::unique_ptr<WebRtcMedium> medium)
WebRtcImpl::WebRtcImpl(std::unique_ptr<WebRtcMedium> medium)
: medium_(std::move(medium)) {}
WebRtc::~WebRtc() {
WebRtcImpl::~WebRtcImpl() {
// This ensures that all pending callbacks are run before we reset the medium
// and we are not accepting new runnables.
single_thread_executor_.Shutdown();
@@ -80,26 +81,26 @@ WebRtc::~WebRtc() {
}
}
std::string WebRtc::GetDefaultCountryCode() {
std::string WebRtcImpl::GetDefaultCountryCode() {
return medium_->GetDefaultCountryCode();
}
bool WebRtc::IsAvailable() { return medium_->IsValid(); }
bool WebRtcImpl::IsAvailable() { return medium_->IsValid(); }
bool WebRtc::IsAcceptingConnections(const std::string& service_id) {
bool WebRtcImpl::IsAcceptingConnections(const std::string& service_id) {
MutexLock lock(&mutex_);
return IsAcceptingConnectionsLocked(service_id);
}
bool WebRtc::IsAcceptingConnectionsLocked(const std::string& service_id) {
bool WebRtcImpl::IsAcceptingConnectionsLocked(const std::string& service_id) {
return accepting_connections_info_.contains(service_id);
}
bool WebRtc::StartAcceptingConnections(const std::string& service_id,
const WebrtcPeerId& self_peer_id,
const LocationHint& location_hint,
AcceptedConnectionCallback callback,
bool non_cellular) {
bool WebRtcImpl::StartAcceptingConnections(const std::string& service_id,
const WebrtcPeerId& self_peer_id,
const LocationHint& location_hint,
AcceptedConnectionCallback callback,
bool non_cellular) {
MutexLock lock(&mutex_);
if (!IsAvailable()) {
LOG(WARNING) << "Cannot start accepting WebRTC connections because "
@@ -131,8 +132,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.
if (!info.signaling_messenger->StartReceivingMessages(
absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id),
absl::bind_front(&WebRtc::OnSignalingComplete, this, service_id))) {
absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id),
absl::bind_front(&WebRtcImpl::OnSignalingComplete, this,
service_id))) {
info.signaling_messenger.reset();
return false;
}
@@ -142,7 +144,7 @@ bool WebRtc::StartAcceptingConnections(const std::string& service_id,
info.restart_tachyon_receive_messages_alarm =
std::make_unique<CancelableAlarm>(
"restart_receiving_messages_webrtc",
std::bind(&WebRtc::ProcessRestartTachyonReceiveMessages, this,
std::bind(&WebRtcImpl::ProcessRestartTachyonReceiveMessages, this,
service_id),
kRestartReceiveMessagesDuration, &single_thread_executor_);
@@ -154,7 +156,7 @@ bool WebRtc::StartAcceptingConnections(const std::string& service_id,
return true;
}
void WebRtc::StopAcceptingConnections(const std::string& service_id) {
void WebRtcImpl::StopAcceptingConnections(const std::string& service_id) {
MutexLock lock(&mutex_);
if (!IsAcceptingConnectionsLocked(service_id)) {
LOG(WARNING) << "Cannot stop accepting WebRTC connections because service "
@@ -207,7 +209,7 @@ void WebRtc::StopAcceptingConnections(const std::string& service_id) {
<< service_id;
}
ErrorOr<std::shared_ptr<WebRtcSocket>> WebRtc::Connect(
ErrorOr<std::shared_ptr<WebRtcSocket>> WebRtcImpl::Connect(
const std::string& service_id, const WebrtcPeerId& remote_peer_id,
const LocationHint& location_hint, CancellationFlag* cancellation_flag,
bool non_cellular) {
@@ -242,7 +244,7 @@ ErrorOr<std::shared_ptr<WebRtcSocket>> WebRtc::Connect(
return {Error(wrapper_result.error().operation_result_code().value())};
}
ErrorOr<std::shared_ptr<WebRtcSocket>> WebRtc::AttemptToConnect(
ErrorOr<std::shared_ptr<WebRtcSocket>> WebRtcImpl::AttemptToConnect(
const std::string& service_id, const WebrtcPeerId& remote_peer_id,
const LocationHint& location_hint, CancellationFlag* cancellation_flag) {
ConnectionRequestInfo info = ConnectionRequestInfo();
@@ -298,7 +300,7 @@ ErrorOr<std::shared_ptr<WebRtcSocket>> WebRtc::AttemptToConnect(
}
};
if (!info.signaling_messenger->StartReceivingMessages(
absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id),
absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id),
signaling_complete_callback)) {
LOG(INFO)
<< "Cannot connect to WebRTC peer " << remote_peer_id.GetId()
@@ -360,7 +362,7 @@ ErrorOr<std::shared_ptr<WebRtcSocket>> WebRtc::AttemptToConnect(
}
}
void WebRtc::ProcessLocalIceCandidate(
void WebRtcImpl::ProcessLocalIceCandidate(
const std::string& service_id, const WebrtcPeerId& remote_peer_id,
const location::nearby::mediums::IceCandidate ice_candidate) {
MutexLock lock(&mutex_);
@@ -407,14 +409,15 @@ void WebRtc::ProcessLocalIceCandidate(
<< service_id;
}
void WebRtc::OnSignalingMessage(const std::string& service_id,
const ByteArray& message) {
void WebRtcImpl::OnSignalingMessage(const std::string& service_id,
const ByteArray& message) {
OffloadFromThread("rtc-on-signaling-message", [this, service_id, message]() {
ProcessTachyonInboxMessage(service_id, message);
});
}
void WebRtc::OnSignalingComplete(const std::string& service_id, bool success) {
void WebRtcImpl::OnSignalingComplete(const std::string& service_id,
bool success) {
LOG(INFO) << "Signaling completed with status: " << success;
if (success) {
return;
@@ -438,8 +441,8 @@ void WebRtc::OnSignalingComplete(const std::string& service_id, bool success) {
});
}
void WebRtc::ProcessTachyonInboxMessage(const std::string& service_id,
const ByteArray& message) {
void WebRtcImpl::ProcessTachyonInboxMessage(const std::string& service_id,
const ByteArray& message) {
MutexLock lock(&mutex_);
// Attempt to parse the incoming message as a WebRtcSignalingFrame.
@@ -492,8 +495,8 @@ void WebRtc::ProcessTachyonInboxMessage(const std::string& service_id,
}
}
void WebRtc::SendOffer(const std::string& service_id,
const WebrtcPeerId& remote_peer_id) {
void WebRtcImpl::SendOffer(const std::string& service_id,
const WebrtcPeerId& remote_peer_id) {
std::unique_ptr<ConnectionFlow> connection_flow =
CreateConnectionFlow(service_id, remote_peer_id);
if (!connection_flow) {
@@ -534,8 +537,8 @@ void WebRtc::SendOffer(const std::string& service_id,
LOG(INFO) << "Sent offer to " << remote_peer_id.GetId();
}
void WebRtc::ReceiveOffer(const WebrtcPeerId& remote_peer_id,
SessionDescriptionWrapper offer) {
void WebRtcImpl::ReceiveOffer(const WebrtcPeerId& remote_peer_id,
SessionDescriptionWrapper offer) {
const auto& entry = connection_flows_.find(remote_peer_id.GetId());
if (entry == connection_flows_.end()) {
LOG(INFO) << "Unable to receive offer. Failed to create a ConnectionFlow.";
@@ -548,7 +551,7 @@ void WebRtc::ReceiveOffer(const WebrtcPeerId& remote_peer_id,
}
}
void WebRtc::SendAnswer(const WebrtcPeerId& remote_peer_id) {
void WebRtcImpl::SendAnswer(const WebrtcPeerId& remote_peer_id) {
const auto& entry = connection_flows_.find(remote_peer_id.GetId());
if (entry == connection_flows_.end()) {
LOG(INFO) << "Unable to send answer. Failed to create a ConnectionFlow.";
@@ -596,8 +599,8 @@ void WebRtc::SendAnswer(const WebrtcPeerId& remote_peer_id) {
LOG(INFO) << "Sent answer to " << remote_peer_id.GetId();
}
void WebRtc::ReceiveAnswer(const WebrtcPeerId& remote_peer_id,
SessionDescriptionWrapper answer) {
void WebRtcImpl::ReceiveAnswer(const WebrtcPeerId& remote_peer_id,
SessionDescriptionWrapper answer) {
const auto& entry = connection_flows_.find(remote_peer_id.GetId());
if (entry == connection_flows_.end()) {
LOG(INFO) << "Unable to receive answer. Failed to create a ConnectionFlow.";
@@ -610,7 +613,7 @@ void WebRtc::ReceiveAnswer(const WebrtcPeerId& remote_peer_id,
}
}
void WebRtc::ReceiveIceCandidates(
void WebRtcImpl::ReceiveIceCandidates(
const WebrtcPeerId& remote_peer_id,
std::vector<std::unique_ptr<webrtc::IceCandidate>> ice_candidates) {
const auto& entry = connection_flows_.find(remote_peer_id.GetId());
@@ -623,13 +626,13 @@ void WebRtc::ReceiveIceCandidates(
entry->second->OnRemoteIceCandidatesReceived(std::move(ice_candidates));
}
void WebRtc::ProcessRestartTachyonReceiveMessages(
void WebRtcImpl::ProcessRestartTachyonReceiveMessages(
const std::string& service_id) {
MutexLock lock(&mutex_);
RestartTachyonReceiveMessages(service_id);
}
void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) {
void WebRtcImpl::RestartTachyonReceiveMessages(const std::string& service_id) {
if (!IsAcceptingConnectionsLocked(service_id)) {
LOG(INFO)
<< "Skipping restart listening for tachyon inbox messages since we are "
@@ -646,8 +649,9 @@ void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) {
// Attempt to re-register.
if (!info.signaling_messenger->StartReceivingMessages(
absl::bind_front(&WebRtc::OnSignalingMessage, this, service_id),
absl::bind_front(&WebRtc::OnSignalingComplete, this, service_id))) {
absl::bind_front(&WebRtcImpl::OnSignalingMessage, this, service_id),
absl::bind_front(&WebRtcImpl::OnSignalingComplete, this,
service_id))) {
LOG(WARNING)
<< "Failed to restart listening for tachyon inbox messages for "
"service "
@@ -660,7 +664,7 @@ void WebRtc::RestartTachyonReceiveMessages(const std::string& service_id) {
<< service_id;
}
void WebRtc::ProcessDataChannelOpen(
void WebRtcImpl::ProcessDataChannelOpen(
const std::string& service_id, const WebrtcPeerId& remote_peer_id,
std::shared_ptr<WebRtcSocket> socket_wrapper) {
MutexLock lock(&mutex_);
@@ -689,7 +693,7 @@ void WebRtc::ProcessDataChannelOpen(
<< service_id;
}
void WebRtc::ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) {
void WebRtcImpl::ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) {
MutexLock lock(&mutex_);
LOG(INFO) << "Data channel has closed, removing connection flow for peer "
<< remote_peer_id.GetId();
@@ -697,7 +701,7 @@ void WebRtc::ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id) {
RemoveConnectionFlow(remote_peer_id);
}
std::unique_ptr<ConnectionFlow> WebRtc::CreateConnectionFlow(
std::unique_ptr<ConnectionFlow> WebRtcImpl::CreateConnectionFlow(
const std::string& service_id, const WebrtcPeerId& remote_peer_id) {
RemoveConnectionFlow(remote_peer_id);
@@ -749,7 +753,7 @@ std::unique_ptr<ConnectionFlow> WebRtc::CreateConnectionFlow(
*medium_);
}
void WebRtc::AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) {
void WebRtcImpl::AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) {
MutexLock lock(&mutex_);
is_using_cellular_ = adapter_type == webrtc::ADAPTER_TYPE_CELLULAR ||
adapter_type == webrtc::ADAPTER_TYPE_CELLULAR_2G ||
@@ -758,7 +762,7 @@ void WebRtc::AdapterTypeChangedHandler(webrtc::AdapterType adapter_type) {
adapter_type == webrtc::ADAPTER_TYPE_CELLULAR_5G;
}
void WebRtc::RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) {
void WebRtcImpl::RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) {
if (!connection_flows_.erase(remote_peer_id.GetId())) {
return;
}
@@ -773,11 +777,11 @@ void WebRtc::RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id) {
}
}
void WebRtc::OffloadFromThread(const std::string& name, Runnable runnable) {
void WebRtcImpl::OffloadFromThread(const std::string& name, Runnable runnable) {
single_thread_executor_.Execute(name, std::move(runnable));
}
bool WebRtc::IsUsingCellular() {
bool WebRtcImpl::IsUsingCellular() {
MutexLock lock(&mutex_);
return is_using_cellular_;
}
@@ -786,4 +790,4 @@ bool WebRtc::IsUsingCellular() {
} // namespace connections
} // namespace nearby
#endif
#endif // NO_WEBRTC
@@ -0,0 +1,254 @@
// 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_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_
#define CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_
#ifndef NO_WEBRTC
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "connections/implementation/mediums/webrtc.h"
#include "connections/implementation/mediums/webrtc/connection_flow.h"
#include "connections/implementation/mediums/webrtc/session_description_wrapper.h"
#include "connections/implementation/mediums/webrtc_peer_id.h"
#include "connections/implementation/mediums/webrtc_socket.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/cancelable_alarm.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/expected.h"
#include "internal/platform/future.h"
#include "internal/platform/mutex.h"
#include "internal/platform/runnable.h"
#include "internal/platform/scheduled_executor.h"
#include "internal/platform/webrtc.h"
#include "proto/mediums/web_rtc_signaling_frames.pb.h"
#include "webrtc/api/jsep.h"
#include "webrtc/rtc_base/network_constants.h"
namespace nearby {
namespace connections {
namespace mediums {
// Entry point for connecting a data channel between two devices via WebRtc.
class WebRtcImpl : public WebRtc {
public:
WebRtcImpl();
~WebRtcImpl() override;
// Overrides for WebRtc:
std::string GetDefaultCountryCode() override;
bool IsAvailable() override;
bool IsAcceptingConnections(const std::string& service_id) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool StartAcceptingConnections(
const std::string& service_id, const WebrtcPeerId& self_peer_id,
const location::nearby::connections::LocationHint& location_hint,
AcceptedConnectionCallback callback, bool non_cellular) override
ABSL_LOCKS_EXCLUDED(mutex_);
void StopAcceptingConnections(const std::string& service_id) override
ABSL_LOCKS_EXCLUDED(mutex_);
ErrorOr<std::shared_ptr<WebRtcSocket>> Connect(
const std::string& service_id, const WebrtcPeerId& peer_id,
const location::nearby::connections::LocationHint& location_hint,
CancellationFlag* cancellation_flag, bool non_cellular) override
ABSL_LOCKS_EXCLUDED(mutex_);
bool IsUsingCellular() override ABSL_LOCKS_EXCLUDED(mutex_);
protected:
// Use for unit tests only to inject a WebRtcMedium.
explicit WebRtcImpl(std::unique_ptr<WebRtcMedium> medium);
// Used in unit tests to determine how many calls to `AttemptToConnect`
// occured during a call to `Connect`, per service id.
std::map<std::string, int> service_id_to_connect_attempts_count_map_;
private:
static constexpr int kConnectAttemptsLimit = 3;
static constexpr int kRestartAcceptConnectionsLimit = 3;
enum class Role {
kNone = 0,
kOfferer = 1,
kAnswerer = 2,
};
struct AcceptingConnectionsInfo {
// The self_peer_id is generated from the BT/WiFi advertisements and allows
// the scanner to message us over Tachyon.
WebrtcPeerId self_peer_id;
// The registered callback. When there's an incoming connection, this
// callback is notified.
AcceptedConnectionCallback accepted_connection_callback;
// Allows us to communicate with the Tachyon web server.
std::unique_ptr<WebRtcSignalingMessenger> signaling_messenger;
// Restarts the tachyon inbox receives messages streaming rpc if the
// streaming rpc times out. The streaming rpc times out after 60s while
// advertising. Non-null when listening for WebRTC connections as an
// offerer.
std::unique_ptr<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 {
// The self_peer_id is randomly generated and allows the advertiser to
// message us over Tachyon.
WebrtcPeerId self_peer_id;
// Allows us to communicate with the Tachyon web server.
std::unique_ptr<WebRtcSignalingMessenger> signaling_messenger;
// The pending DataChannel future. Our client will be blocked on this while
// they wait for us to set up the channel over Tachyon.
Future<std::shared_ptr<WebRtcSocket>> socket_future;
};
// Attempt to initiates a WebRtc connection with peer device identified by
// |peer_id|.
// Runs on @MainThread.
ErrorOr<std::shared_ptr<WebRtcSocket>> AttemptToConnect(
const std::string& service_id, const WebrtcPeerId& peer_id,
const location::nearby::connections::LocationHint& location_hint,
CancellationFlag* cancellation_flag) ABSL_LOCKS_EXCLUDED(mutex_);
// Returns if the device is accepting connection with specific service id.
// Runs on @MainThread.
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)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
void SendOffer(const std::string& service_id,
const WebrtcPeerId& remote_peer_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void ReceiveOffer(const WebrtcPeerId& remote_peer_id,
SessionDescriptionWrapper offer)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void SendAnswer(const WebrtcPeerId& remote_peer_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void ReceiveAnswer(const WebrtcPeerId& remote_peer_id,
SessionDescriptionWrapper answer)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void ReceiveIceCandidates(
const WebrtcPeerId& remote_peer_id,
std::vector<std::unique_ptr<webrtc::IceCandidate>> ice_candidates)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
std::unique_ptr<ConnectionFlow> CreateConnectionFlow(
const std::string& service_id, const WebrtcPeerId& remote_peer_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
std::unique_ptr<ConnectionFlow> GetConnectionFlow(
const WebrtcPeerId& remote_peer_id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void RemoveConnectionFlow(const WebrtcPeerId& remote_peer_id)
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
// Runs on |single_thread_executor_|.
void ProcessDataChannelOpen(const std::string& service_id,
const WebrtcPeerId& remote_peer_id,
std::shared_ptr<WebRtcSocket> socket_wrapper)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
void ProcessDataChannelClosed(const WebrtcPeerId& remote_peer_id)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
void ProcessLocalIceCandidate(
const std::string& service_id, const WebrtcPeerId& remote_peer_id,
location::nearby::mediums::IceCandidate ice_candidate)
ABSL_LOCKS_EXCLUDED(mutex_);
// Runs on |single_thread_executor_|.
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_);
// Runs on |single_thread_executor_|.
void AdapterTypeChangedHandler(webrtc::AdapterType adapter_type)
ABSL_LOCKS_EXCLUDED(mutex_);
void OffloadFromThread(const std::string& name, Runnable runnable);
Mutex mutex_;
std::unique_ptr<WebRtcMedium> medium_;
// The single thread we throw the potentially blocking work on to.
ScheduledExecutor single_thread_executor_;
// A map of ServiceID -> State for all services that are listening for
// incoming connections.
absl::flat_hash_map<std::string, AcceptingConnectionsInfo>
accepting_connections_info_ ABSL_GUARDED_BY(mutex_);
// A map of a remote PeerId -> State for pending connection requests. As
// messages from Tachyon come in, this lets us look up the connection request
// info to handle the interaction.
absl::flat_hash_map<std::string, ConnectionRequestInfo>
requesting_connections_info_ ABSL_GUARDED_BY(mutex_);
// A map of a remote PeerId -> ConnectionFlow. For each connection, we create
// a unique ConnectionFlow.
absl::flat_hash_map<std::string, std::unique_ptr<ConnectionFlow>>
connection_flows_ ABSL_GUARDED_BY(mutex_);
bool is_using_cellular_ ABSL_GUARDED_BY(mutex_) = true;
};
} // namespace mediums
} // namespace connections
} // namespace nearby
#endif // NO_WEBRTC
#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_WEBRTC_IMPL_H_
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/mediums/webrtc.h"
#include "connections/implementation/mediums/webrtc/webrtc_impl.h"
#include <memory>
#include <string>
@@ -48,10 +48,10 @@ struct WebRtcTestParams {
bool non_cellular;
};
class TestWebRtc : public WebRtc {
class TestWebRtc : public WebRtcImpl {
public:
explicit TestWebRtc(std::unique_ptr<WebRtcMedium> medium)
: WebRtc(std::move(medium)) {}
: WebRtcImpl(std::move(medium)) {}
int connect_attempts_count(std::string service_id) {
return service_id_to_connect_attempts_count_map_[service_id];
@@ -72,7 +72,7 @@ TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) {
env_.Start({.webrtc_enabled = true});
WebRtcTestParams params = GetParam();
env_.SetFeatureFlags(params.feature_flags);
WebRtc receiver, sender;
WebRtcImpl receiver, sender;
std::shared_ptr<WebRtcSocket> receiver_socket;
const WebrtcPeerId self_id("self_id");
const std::string service_id("NearbySharing");
@@ -93,7 +93,7 @@ TEST_P(WebRtcTest, ConnectBothDevices_ShutdownSignaling_SendData) {
CancellationFlag flag;
ErrorOr<std::shared_ptr<WebRtcSocket>> sender_socket_result = sender.Connect(
service_id, self_id, location_hint, &flag, params.non_cellular);
EXPECT_TRUE(sender_socket_result.has_value());
ASSERT_TRUE(sender_socket_result.has_value());
EXPECT_TRUE(sender_socket_result.value()->IsValid());
ExceptionOr<bool> devices_connected = connected.Get();
@@ -115,7 +115,7 @@ TEST_P(WebRtcTest, CanCancelConnect) {
env_.Start({.webrtc_enabled = true});
WebRtcTestParams params = GetParam();
env_.SetFeatureFlags(params.feature_flags);
WebRtc receiver, sender;
WebRtcImpl receiver, sender;
std::shared_ptr<WebRtcSocket> receiver_socket;
const WebrtcPeerId self_id("self_id");
const std::string service_id("NearbySharing");
@@ -138,7 +138,7 @@ TEST_P(WebRtcTest, CanCancelConnect) {
service_id, self_id, location_hint, &flag, params.non_cellular);
// If FeatureFlag is disabled, Cancelled is false as no-op.
if (!params.feature_flags.enable_cancellation_flag) {
EXPECT_TRUE(sender_socket_result.has_value());
ASSERT_TRUE(sender_socket_result.has_value());
EXPECT_TRUE(sender_socket_result.value()->IsValid());
ExceptionOr<bool> devices_connected = connected.Get();
@@ -161,7 +161,7 @@ TEST_P(WebRtcTest, CanCancelConnect) {
// Basic test to check that device is accepting connections when initialized.
TEST_P(WebRtcTest, NotAcceptingConnections) {
env_.Start({.webrtc_enabled = true});
WebRtc webrtc;
WebRtcImpl webrtc;
ASSERT_TRUE(webrtc.IsAvailable());
EXPECT_FALSE(webrtc.IsAcceptingConnections(std::string{}));
env_.Stop();
@@ -173,7 +173,7 @@ TEST_P(WebRtcTest, StartAcceptingConnectionTwice) {
env_.Start({.webrtc_enabled = true});
WebRtcTestParams params = GetParam();
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
WebRtc webrtc;
WebRtcImpl webrtc;
WebrtcPeerId self_id("peer_id");
const std::string service_id("NearbySharing");
LocationHint location_hint{};
@@ -195,7 +195,7 @@ TEST_P(WebRtcTest, StartAcceptingConnectionTwice) {
TEST_P(WebRtcTest, Connect_NoPeer) {
env_.Start({.webrtc_enabled = true});
WebRtcTestParams params = GetParam();
WebRtc webrtc;
WebRtcImpl webrtc;
WebrtcPeerId peer_id("peer_id");
const std::string service_id("NearbySharing");
LocationHint location_hint;
@@ -217,7 +217,7 @@ TEST_P(WebRtcTest, StartAcceptingConnection_ThenConnect) {
env_.Start({.webrtc_enabled = true});
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
WebRtcTestParams params = GetParam();
WebRtc webrtc;
WebRtcImpl webrtc;
WebrtcPeerId self_id("peer_id");
const std::string service_id("NearbySharing");
LocationHint location_hint;
@@ -244,7 +244,7 @@ TEST_P(WebRtcTest, StartAndStopAcceptingConnections) {
env_.Start({.webrtc_enabled = true});
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
WebRtcTestParams params = GetParam();
WebRtc webrtc;
WebRtcImpl webrtc;
WebrtcPeerId self_id("peer_id");
const std::string service_id("NearbySharing");
LocationHint location_hint;
@@ -263,7 +263,7 @@ TEST_P(WebRtcTest, StartAndStopAcceptingConnections) {
// without disconnecting in between.
TEST_P(WebRtcTest, ConnectTwice) {
env_.Start({.webrtc_enabled = true});
WebRtc receiver, sender, device_c;
WebRtcImpl receiver, sender, device_c;
std::shared_ptr<WebRtcSocket> receiver_socket;
WebRtcTestParams params = GetParam();
const WebrtcPeerId self_id("self_id"), other_id("other_id");
@@ -291,7 +291,7 @@ TEST_P(WebRtcTest, ConnectTwice) {
CancellationFlag flag;
ErrorOr<std::shared_ptr<WebRtcSocket>> sender_socket_result = sender.Connect(
service_id, self_id, location_hint, &flag, params.non_cellular);
EXPECT_TRUE(sender_socket_result.has_value());
ASSERT_TRUE(sender_socket_result.has_value());
EXPECT_TRUE(sender_socket_result.value()->IsValid());
ExceptionOr<bool> devices_connected = connected.Get();
@@ -305,7 +305,7 @@ TEST_P(WebRtcTest, ConnectTwice) {
socket_result.value()->Close();
EXPECT_TRUE(receiver_socket->IsValid());
EXPECT_TRUE(sender_socket_result.has_value());
ASSERT_TRUE(sender_socket_result.has_value());
EXPECT_TRUE(sender_socket_result.value()->IsValid());
sender_socket_result.value()->GetOutputStream().Write(message);
@@ -322,7 +322,7 @@ TEST_P(WebRtcTest, ConnectTwice) {
// other but disconnect before being able to send/receive the actual data.
TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) {
env_.Start({.webrtc_enabled = true});
WebRtc receiver, sender;
WebRtcImpl receiver, sender;
std::shared_ptr<WebRtcSocket> receiver_socket, sender_socket;
WebRtcTestParams params = GetParam();
const WebrtcPeerId self_id("self_id");
@@ -343,7 +343,7 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) {
CancellationFlag flag;
ErrorOr<std::shared_ptr<WebRtcSocket>> sender_socket_result = sender.Connect(
service_id, self_id, location_hint, &flag, params.non_cellular);
EXPECT_TRUE(sender_socket_result.has_value());
ASSERT_TRUE(sender_socket_result.has_value());
EXPECT_TRUE(sender_socket_result.value()->IsValid());
ExceptionOr<bool> devices_connected = connected.Get();
@@ -358,7 +358,7 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndAbort) {
// other and the actual data is exchanged successfully between the devices.
TEST_P(WebRtcTest, ConnectBothDevicesAndSendData) {
env_.Start({.webrtc_enabled = true});
WebRtc receiver, sender;
WebRtcImpl receiver, sender;
std::shared_ptr<WebRtcSocket> receiver_socket;
WebRtcTestParams params = GetParam();
const WebrtcPeerId self_id("self_id");
@@ -380,7 +380,7 @@ TEST_P(WebRtcTest, ConnectBothDevicesAndSendData) {
CancellationFlag flag;
ErrorOr<std::shared_ptr<WebRtcSocket>> sender_socket_result = sender.Connect(
service_id, self_id, location_hint, &flag, params.non_cellular);
EXPECT_TRUE(sender_socket_result.has_value());
ASSERT_TRUE(sender_socket_result.has_value());
EXPECT_TRUE(sender_socket_result.value()->IsValid());
ExceptionOr<bool> devices_connected = connected.Get();
@@ -404,7 +404,7 @@ TEST_P(WebRtcTest, Connect_NullPeerConnection) {
env_.SetUseValidPeerConnection(
/*use_valid_peer_connection=*/false);
WebRtc webrtc;
WebRtcImpl webrtc;
const std::string service_id("NearbySharing");
WebrtcPeerId self_id("peer_id");
LocationHint location_hint;
@@ -424,7 +424,7 @@ TEST_P(WebRtcTest, ContinueAcceptingConnectionsOnComplete) {
env_.Start({.webrtc_enabled = true});
testing::StrictMock<MockAcceptedCallback> mock_accepted_callback_;
WebRtcTestParams params = GetParam();
WebRtc webrtc;
WebRtcImpl webrtc;
WebrtcPeerId self_id("peer_id");
const std::string service_id("NearbySharing");
LocationHint location_hint;
@@ -595,7 +595,7 @@ TEST_P(WebRtcTest, CancelDuringConnect_MultipleConnect) {
// Simulate a successful connect for the endpoint of NearbySharing.
ErrorOr<std::shared_ptr<WebRtcSocket>> sender_socket_result = sender->Connect(
ns_service_id, self_id, location_hint, &flag, params.non_cellular);
EXPECT_TRUE(sender_socket_result.has_value());
ASSERT_TRUE(sender_socket_result.has_value());
EXPECT_TRUE(sender_socket_result.value()->IsValid());
// Calls `CancellationFlag::Cancel` during a call to `GetSignalingMessenger`
@@ -1,67 +0,0 @@
// 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.
#ifdef NO_WEBRTC
#include "connections/implementation/mediums/webrtc_stub.h"
#include <functional>
#include <memory>
#include "connections/implementation/mediums/webrtc_socket.h"
#include "internal/platform/cancelable_alarm.h"
#include "internal/platform/expected.h"
#include "internal/platform/future.h"
#include "internal/platform/listeners.h"
namespace nearby {
namespace connections {
namespace mediums {
using ::location::nearby::connections::LocationHint;
using ::location::nearby::proto::connections::OperationResultCode;
WebRtc::WebRtc() = default;
WebRtc::~WebRtc() {}
std::string WebRtc::GetDefaultCountryCode() { return "US"; }
bool WebRtc::IsAvailable() { return false; }
bool WebRtc::IsAcceptingConnections(const std::string& service_id) {
return false;
}
bool WebRtc::StartAcceptingConnections(const std::string& service_id,
const WebrtcPeerId& self_peer_id,
const LocationHint& location_hint,
AcceptedConnectionCallback callback) {
return false;
}
void WebRtc::StopAcceptingConnections(const std::string& service_id) {}
ErrorOr<std::shared_ptr<WebRtcSocket>> WebRtc::Connect(
const std::string& service_id, const WebrtcPeerId& remote_peer_id,
const LocationHint& location_hint, CancellationFlag* cancellation_flag) {
return {Error(OperationResultCode::DETAIL_UNKNOWN)};
}
bool WebRtc::IsUsingCellular() { return false; }
} // namespace mediums
} // namespace connections
} // namespace nearby
#endif
@@ -1,86 +0,0 @@
// 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_INTERNAL_MEDIUMS_WEBRTC_STUB_H_
#define CORE_INTERNAL_MEDIUMS_WEBRTC_STUB_H_
#ifdef NO_WEBRTC
#include <cstddef>
#include <functional>
#include <memory>
#include <string>
#include "connections/implementation/mediums/webrtc_peer_id.h"
#include "connections/implementation/mediums/webrtc_socket.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/expected.h"
#include "internal/platform/listeners.h"
namespace nearby {
namespace connections {
namespace mediums {
// Entry point for connecting a data channel between two devices via WebRtc.
class WebRtc {
public:
// Callback that is invoked when a new connection is accepted.
using AcceptedConnectionCallback =
absl::AnyInvocable<void(std::shared_ptr<WebRtcSocket> socket)>;
WebRtc();
~WebRtc();
// Gets the default two-letter country code associated with current locale.
// For example, en_US locale resolves to "US".
std::string GetDefaultCountryCode();
// Returns if WebRtc is available as a medium for nearby to transport data.
// Runs on @MainThread.
bool IsAvailable();
// Returns if the device is accepting connection with specific service id.
// Runs on @MainThread.
bool IsAcceptingConnections(const std::string& service_id);
// Prepares the device to accept incoming WebRtc connections. Returns a
// boolean value indicating if the device has started accepting connections.
// Runs on @MainThread.
bool StartAcceptingConnections(
const std::string& service_id, const WebrtcPeerId& self_peer_id,
const location::nearby::connections::LocationHint& location_hint,
AcceptedConnectionCallback callback);
// Try to stop (accepting) the specific connection with provided service id.
// Runs on @MainThread
void StopAcceptingConnections(const std::string& service_id);
// Initiates a WebRtc connection with peer device identified by |peer_id|
// with internal retry for maximum attempts of kConnectAttemptsLimit.
// Runs on @MainThread.
ErrorOr<std::shared_ptr<WebRtcSocket>> Connect(
const std::string& service_id, const WebrtcPeerId& peer_id,
const location::nearby::connections::LocationHint& location_hint,
CancellationFlag* cancellation_flag);
bool IsUsingCellular();
};
} // namespace mediums
} // namespace connections
} // namespace nearby
#endif
#endif // CORE_INTERNAL_MEDIUMS_WEBRTC_STUB_H_
@@ -55,11 +55,7 @@
#include "internal/platform/bluetooth_classic.h"
#include "internal/platform/nsd_service_info.h"
#include "internal/platform/wifi_lan.h"
#ifdef NO_WEBRTC
#include "connections/implementation/mediums/webrtc_stub.h"
#else
#include "connections/implementation/mediums/webrtc.h"
#endif
#include "connections/implementation/pcp.h"
#include "connections/implementation/wifi_lan_service_info.h"
#include "internal/platform/byte_array.h"