Add WebRtcMedium implementation for Windows.

PiperOrigin-RevId: 531631988
This commit is contained in:
hai007
2023-05-12 16:29:40 -07:00
committed by Copybara-Service
parent b07700629d
commit b9a4d98e25
5 changed files with 222 additions and 28 deletions
@@ -108,17 +108,20 @@ cc_library(
"//internal/platform:base",
"//internal/platform:comm",
"//internal/platform:types",
"//internal/platform:uuid",
"//internal/platform/implementation:comm",
"//internal/platform/implementation:types",
"//internal/platform/implementation/windows/generated:types",
"@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:any_invocable",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
],
)
@@ -167,6 +170,7 @@ cc_library(
"system_clock.cc",
"thread_pool.cc",
"utils.cc",
"webrtc.cc",
"wifi_direct_medium.cc",
"wifi_direct_server_socket.cc",
"wifi_direct_socket.cc",
@@ -206,6 +210,8 @@ cc_library(
"//internal/platform/implementation/shared:count_down_latch",
"//internal/platform/implementation/shared:file",
"//internal/platform/implementation/windows/generated:types",
"//third_party/webrtc/files/stable/webrtc/api/task_queue:default_task_queue_factory",
"//third_party/webrtc/files/stable/webrtc/rtc_base:checks",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/functional:any_invocable",
@@ -218,7 +224,6 @@ cc_library(
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:optional",
"@com_google_absl//absl/types:span",
"@nlohmann_json//:json",
],
)
@@ -265,6 +270,7 @@ cc_test(
"thread_pool_test.cc",
"timer_test.cc",
"utils_test.cc",
"webrtc_test.cc",
],
copts = ["-Ithird_party/nearby/internal/platform/implementation/windows/generated -DCORE_ADAPTER_DLL"],
tags = ["notap"],
@@ -301,7 +301,7 @@ ImplementationPlatform::CreateWifiDirectMedium() {
return nullptr;
}
// TODO(b/184975123): replace with real implementation.
// TODO(b/261663238) replace with real implementation.
std::unique_ptr<WebRtcMedium> ImplementationPlatform::CreateWebRtcMedium() {
return nullptr;
}
@@ -0,0 +1,112 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/implementation/windows/webrtc.h"
#include <winnls.h>
#include <memory>
#include <string>
#include <utility>
#include "internal/platform/logging.h"
#include "webrtc/api/task_queue/default_task_queue_factory.h"
namespace nearby {
namespace windows {
WebRtcSignalingMessenger::WebRtcSignalingMessenger(
absl::string_view self_id,
const location::nearby::connections::LocationHint& location_hint)
: self_id_(self_id), location_hint_(location_hint) {}
// TODO(b/261663238): replace with real implementation.
bool WebRtcSignalingMessenger::SendMessage(absl::string_view peer_id,
const ByteArray& message) {
return false;
}
// TODO(b/261663238): replace with real implementation.
bool WebRtcSignalingMessenger::StartReceivingMessages(
api::WebRtcSignalingMessenger::OnSignalingMessageCallback
on_message_callback,
api::WebRtcSignalingMessenger::OnSignalingCompleteCallback
on_complete_callback) {
return false;
}
// TODO(b/261663238): replace with real implementation.
void WebRtcSignalingMessenger::StopReceivingMessages() {}
const std::string WebRtcMedium::GetDefaultCountryCode() {
wchar_t systemGeoName[LOCALE_NAME_MAX_LENGTH];
if (!GetUserDefaultGeoName(systemGeoName, LOCALE_NAME_MAX_LENGTH)) {
NEARBY_LOGS(ERROR) << __func__ << ": Failed to GetUserDefaultGeoName: "
<< ". Fall back to US.";
return "US";
}
std::wstring wideGeo(systemGeoName);
std::string systemGeoNameString(wideGeo.begin(), wideGeo.end());
NEARBY_LOGS(VERBOSE) << "GetUserDefaultGeoName() returns: "
<< systemGeoNameString;
return systemGeoNameString;
}
void WebRtcMedium::CreatePeerConnection(
webrtc::PeerConnectionObserver* observer, PeerConnectionCallback callback) {
webrtc::PeerConnectionInterface::RTCConfiguration rtc_config;
rtc_config.sdp_semantics = webrtc::SdpSemantics::kUnifiedPlan;
// TODO(b/261663238): Add the TURN servers and go beyond the default servers.
webrtc::PeerConnectionInterface::IceServer ice_server;
ice_server.urls.emplace_back("stun:stun.l.google.com:19302");
ice_server.urls.emplace_back("stun:stun1.l.google.com:19302");
ice_server.urls.emplace_back("stun:stun2.l.google.com:19302");
ice_server.urls.emplace_back("stun:stun3.l.google.com:19302");
ice_server.urls.emplace_back("stun:stun4.l.google.com:19302");
rtc_config.servers.push_back(ice_server);
std::unique_ptr<rtc::Thread> signaling_thread = rtc::Thread::Create();
signaling_thread->SetName("signaling_thread", nullptr);
if (!signaling_thread->Start()) {
NEARBY_LOGS(FATAL) << "Failed to start thread";
}
webrtc::PeerConnectionDependencies dependencies(observer);
webrtc::PeerConnectionFactoryDependencies factory_dependencies;
factory_dependencies.task_queue_factory =
webrtc::CreateDefaultTaskQueueFactory();
factory_dependencies.signaling_thread = signaling_thread.release();
auto peer_connection_or_error =
webrtc::CreateModularPeerConnectionFactory(
std::move(factory_dependencies))
->CreatePeerConnectionOrError(rtc_config, std::move(dependencies));
if (peer_connection_or_error.ok()) {
callback(peer_connection_or_error.MoveValue());
} else {
NEARBY_LOGS(FATAL) << "Failed to create peer connection";
callback(/*peer_connection=*/nullptr);
}
}
std::unique_ptr<api::WebRtcSignalingMessenger>
WebRtcMedium::GetSignalingMessenger(
absl::string_view self_id,
const location::nearby::connections::LocationHint& location_hint) {
return std::make_unique<WebRtcSignalingMessenger>(std::string(self_id),
location_hint);
}
} // namespace windows
} // namespace nearby
@@ -15,6 +15,8 @@
#ifndef PLATFORM_IMPL_WINDOWS_WEBRTC_H_
#define PLATFORM_IMPL_WINDOWS_WEBRTC_H_
#include <string>
#include "internal/platform/implementation/webrtc.h"
namespace nearby {
@@ -22,53 +24,49 @@ namespace windows {
class WebRtcSignalingMessenger : public api::WebRtcSignalingMessenger {
public:
// TODO(b/184975123): replace with real implementation.
using OnSignalingMessageCallback =
api::WebRtcSignalingMessenger::OnSignalingMessageCallback;
using OnSignalingCompleteCallback =
api::WebRtcSignalingMessenger::OnSignalingCompleteCallback;
explicit WebRtcSignalingMessenger(
absl::string_view self_id,
const location::nearby::connections::LocationHint& location_hint);
~WebRtcSignalingMessenger() override = default;
// TODO(b/184975123): replace with real implementation.
bool SendMessage(absl::string_view peer_id,
const ByteArray& message) override {
return false;
}
// TODO(b/184975123): replace with real implementation.
const ByteArray& message) override;
bool StartReceivingMessages(
api::WebRtcSignalingMessenger::OnSignalingMessageCallback
on_message_callback,
api::WebRtcSignalingMessenger::OnSignalingCompleteCallback
on_complete_callback) override {
return false;
}
// TODO(b/184975123): replace with real implementation.
void StopReceivingMessages() override {}
OnSignalingMessageCallback on_message_callback,
OnSignalingCompleteCallback on_complete_callback) override;
void StopReceivingMessages() override;
private:
std::string self_id_;
location::nearby::connections::LocationHint location_hint_;
};
class WebRtcMedium : public api::WebRtcMedium {
public:
// TODO(b/184975123): replace with real implementation.
// TODO(b/261663238): replace with real implementation.
~WebRtcMedium() override = default;
// Gets the default two-letter country code associated with current locale.
// For example, en_US locale resolves to "US".
// TODO(b/184975123): replace with real implementation.
const std::string GetDefaultCountryCode() override {
return "Un-implemented";
}
// This follows the ISO 3166-1 Alpha-2 standard.
const std::string GetDefaultCountryCode() override;
// Creates and returns a new webrtc::PeerConnectionInterface object via
// |callback|.
// TODO(b/184975123): replace with real implementation.
void CreatePeerConnection(webrtc::PeerConnectionObserver* observer,
PeerConnectionCallback callback) override {}
PeerConnectionCallback callback) override;
// Returns a signaling messenger for sending WebRTC signaling messages.
// TODO(b/184975123): replace with real implementation.
// TODO(b/261663238): replace with real implementation.
std::unique_ptr<api::WebRtcSignalingMessenger> GetSignalingMessenger(
absl::string_view self_id,
const location::nearby::connections::LocationHint& location_hint)
override {
return nullptr;
}
override;
};
} // namespace windows
@@ -0,0 +1,78 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "internal/platform/implementation/windows/webrtc.h"
#include <memory>
#include <string>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
namespace nearby {
namespace windows {
class MockPeerConnectionObserver : public webrtc::PeerConnectionObserver {
public:
void OnSignalingChange(
webrtc::PeerConnectionInterface::SignalingState new_state) override {}
void OnDataChannel(
rtc::scoped_refptr<webrtc::DataChannelInterface> data_channel) override {}
void OnIceGatheringChange(
webrtc::PeerConnectionInterface::IceGatheringState new_state) override {}
void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override {
}
};
location::nearby::connections::LocationHint GetCountryCodeLocationHint(
const std::string& country_code) {
auto location_hint = location::nearby::connections::LocationHint();
location_hint.set_location(country_code);
location_hint.set_format(
location::nearby::connections::LocationStandard::ISO_3166_1_ALPHA_2);
return location_hint;
}
TEST(WebrtcTest, CountryCodeDefault) {
WebRtcMedium medium;
std::string result = medium.GetDefaultCountryCode();
EXPECT_EQ(result, "US");
}
TEST(WebrtcTest, CreatePeerConnectionSucceeds) {
auto observer = std::make_unique<MockPeerConnectionObserver>();
WebRtcMedium medium;
medium.CreatePeerConnection(
observer.get(), [](rtc::scoped_refptr<webrtc::PeerConnectionInterface>
peer_connection) mutable {
if (!peer_connection) {
FAIL() << "Peer connection should have been non-null";
return;
}
});
}
TEST(WebrtcTest, GetSignalingMessengerSucceeds) {
WebRtcMedium medium;
std::unique_ptr<api::WebRtcSignalingMessenger> messenger =
medium.GetSignalingMessenger("US", GetCountryCodeLocationHint("US"));
EXPECT_TRUE(messenger);
}
} // namespace windows
} // namespace nearby