diff options
Diffstat (limited to 'third_party/libwebrtc/api/environment')
7 files changed, 970 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/environment/BUILD.gn b/third_party/libwebrtc/api/environment/BUILD.gn new file mode 100644 index 0000000000..c2b73b327e --- /dev/null +++ b/third_party/libwebrtc/api/environment/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2023 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import("../../webrtc.gni") + +rtc_source_set("environment") { + visibility = [ "*" ] + sources = [ "environment.h" ] + deps = [ + "..:refcountedbase", + "..:scoped_refptr", + "../../rtc_base/system:rtc_export", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/base:nullability" ] +} + +rtc_library("environment_factory") { + visibility = [ "*" ] + poisonous = [ "environment_construction" ] + sources = [ + "environment_factory.cc", + "environment_factory.h", + ] + deps = [ + ":environment", + "..:make_ref_counted", + "..:refcountedbase", + "..:scoped_refptr", + "../../rtc_base:checks", + "../../rtc_base/system:rtc_export", + "../../system_wrappers", + "../rtc_event_log", + "../task_queue:default_task_queue_factory", + "../transport:field_trial_based_config", + ] + absl_deps = [ "//third_party/abseil-cpp/absl/base:nullability" ] +} + +if (rtc_include_tests) { + rtc_library("environment_unittests") { + testonly = true + sources = [ "environment_unittest.cc" ] + deps = [ + ":environment", + ":environment_factory", + "..:field_trials_view", + "../../system_wrappers", + "../../test:test_support", + "../rtc_event_log", + "../task_queue", + "../units:timestamp", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/functional:any_invocable", + "//third_party/abseil-cpp/absl/types:optional", + ] + } +} diff --git a/third_party/libwebrtc/api/environment/OWNERS b/third_party/libwebrtc/api/environment/OWNERS new file mode 100644 index 0000000000..a8af6b5b26 --- /dev/null +++ b/third_party/libwebrtc/api/environment/OWNERS @@ -0,0 +1,15 @@ +# Environment has a limited visibility for stronger control what utilities are +# exposed through it. +# Utilities exposed through environemnt +# - should be helpful for various WebRTC sub components. +# - should be thread safe. +# - should have a default implementation. +# - should provide functionality different to existing utilities in the +# environemnt. +# - should need at most one instance per peer connection. +set noparent +include ../../OWNERS_INFRA + +danilchap@webrtc.org +hta@webrtc.org +mbonadei@webrtc.org diff --git a/third_party/libwebrtc/api/environment/environment.h b/third_party/libwebrtc/api/environment/environment.h new file mode 100644 index 0000000000..d86b7ae780 --- /dev/null +++ b/third_party/libwebrtc/api/environment/environment.h @@ -0,0 +1,148 @@ +/* + * Copyright 2023 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +// This header file provides wrapper for common WebRTC utilities. +// Different application may need different implementations of these utilities, +// Moreover, single application may need to use WebRTC for multiple purposes, +// and thus would need to provide different utilities implementations for +// different peer connections. +// The main purpose of the `Environment` class below is to propagate references +// to those utilities to all WebRTC classes that need them. + +#ifndef API_ENVIRONMENT_ENVIRONMENT_H_ +#define API_ENVIRONMENT_ENVIRONMENT_H_ + +#include <utility> + +#include "absl/base/nullability.h" +#include "api/ref_counted_base.h" +#include "api/scoped_refptr.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +// These classes are forward declared to keep Environment dependencies +// lightweight. Users who need any of the types below should include their +// header explicitely. +class Clock; +class TaskQueueFactory; +class FieldTrialsView; +class RtcEventLog; + +// Contains references to WebRTC utilities. Object of this class should be +// passed as a construction parameter and saved by value in each class that +// needs it. Most classes shouldn't create a new instance of the `Environment`, +// but instead should use a propagated copy. +// Usually Environment should be the first parameter in a constructor or a +// factory, and the first member in the class. Keeping Environment as the first +// member in the class ensures utilities (e.g. clock) are still valid during +// destruction of other members. +// +// Example: +// class PeerConnection { +// public: +// PeerConnection(const Environment& env, ...) +// : env_(env), +// log_duration_on_destruction_(&env_.clock()), +// rtp_manager_(env_, ...), +// ... +// +// const FieldTrialsView& trials() const { return env_.field_trials(); } +// +// scoped_refptr<RtpTransceiverInterface> AddTransceiver(...) { +// return make_ref_counted<RtpTransceiverImpl>(env_, ...); +// } +// +// private: +// const Environment env_; +// Stats log_duration_on_destruction_; +// RtpTransmissionManager rtp_manager_; +// }; +// This class is thread safe. +class RTC_EXPORT Environment final { + public: + // Default constructor is deleted in favor of creating this object using + // `EnvironmentFactory`. To create the default environment use + // `EnvironmentFactory().Create()` or `CreateEnvironment()`. + Environment() = delete; + + Environment(const Environment&) = default; + Environment(Environment&&) = default; + Environment& operator=(const Environment&) = default; + Environment& operator=(Environment&&) = default; + + ~Environment() = default; + + // Provides means to alter behavior, mostly for A/B testing new features. + // See ../../g3doc/field-trials.md + const FieldTrialsView& field_trials() const; + + // Provides an interface to query current time. + // See ../../g3doc/implementation_basics.md#time + Clock& clock() const; + + // Provides a factory for task queues, WebRTC threading primitives. + // See ../../g3doc/implementation_basics.md#threads + TaskQueueFactory& task_queue_factory() const; + + // Provides an interface for collecting structured logs. + // See ../../logging/g3doc/rtc_event_log.md + RtcEventLog& event_log() const; + + private: + friend class EnvironmentFactory; + Environment(scoped_refptr<const rtc::RefCountedBase> storage, + absl::Nonnull<const FieldTrialsView*> field_trials, + absl::Nonnull<Clock*> clock, + absl::Nonnull<TaskQueueFactory*> task_queue_factory, + absl::Nonnull<RtcEventLog*> event_log) + : storage_(std::move(storage)), + field_trials_(field_trials), + clock_(clock), + task_queue_factory_(task_queue_factory), + event_log_(event_log) {} + + // Container that keeps ownership of the utilities below. + // Defining this as a RefCountedBase allows `Environment` to share this + // storage with another `Environment`, in particular allows `Environment` to + // be copyable. It is up to the `EnvironmentFactory` to provide an object that + // ensures references to utilties below are valid while object in the + // `storage_` is alive. + scoped_refptr<const rtc::RefCountedBase> storage_; + + absl::Nonnull<const FieldTrialsView*> field_trials_; + absl::Nonnull<Clock*> clock_; + absl::Nonnull<TaskQueueFactory*> task_queue_factory_; + absl::Nonnull<RtcEventLog*> event_log_; +}; + +//------------------------------------------------------------------------------ +// Implementation details follow +//------------------------------------------------------------------------------ + +inline const FieldTrialsView& Environment::field_trials() const { + return *field_trials_; +} + +inline Clock& Environment::clock() const { + return *clock_; +} + +inline TaskQueueFactory& Environment::task_queue_factory() const { + return *task_queue_factory_; +} + +inline RtcEventLog& Environment::event_log() const { + return *event_log_; +} + +} // namespace webrtc + +#endif // API_ENVIRONMENT_ENVIRONMENT_H_ diff --git a/third_party/libwebrtc/api/environment/environment_factory.cc b/third_party/libwebrtc/api/environment/environment_factory.cc new file mode 100644 index 0000000000..c0b681aa08 --- /dev/null +++ b/third_party/libwebrtc/api/environment/environment_factory.cc @@ -0,0 +1,123 @@ +/* + * Copyright 2023 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/environment/environment_factory.h" + +#include <memory> +#include <utility> +#include <vector> + +#include "api/make_ref_counted.h" +#include "api/rtc_event_log/rtc_event_log.h" +#include "api/task_queue/default_task_queue_factory.h" +#include "api/transport/field_trial_based_config.h" +#include "rtc_base/checks.h" +#include "system_wrappers/include/clock.h" + +namespace webrtc { +namespace { + +template <typename T> +void Store(absl::Nonnull<std::unique_ptr<T>> value, + scoped_refptr<const rtc::RefCountedBase>& leaf) { + class StorageNode : public rtc::RefCountedBase { + public: + StorageNode(scoped_refptr<const rtc::RefCountedBase> parent, + absl::Nonnull<std::unique_ptr<T>> value) + : parent_(std::move(parent)), value_(std::move(value)) {} + + StorageNode(const StorageNode&) = delete; + StorageNode& operator=(const StorageNode&) = delete; + + ~StorageNode() override = default; + + private: + scoped_refptr<const rtc::RefCountedBase> parent_; + absl::Nonnull<std::unique_ptr<T>> value_; + }; + + // Utilities provided with ownership form a tree: + // Root is nullptr, each node keeps an ownership of one utility. + // Each child node has a link to the parent, but parent is unaware of its + // children. Each `EnvironmentFactory` and `Environment` keep a reference to a + // 'leaf_' - node with the last provided utility. This way `Environment` keeps + // ownership of a single branch of the storage tree with each used utiltity + // owned by one of the nodes on that branch. + leaf = rtc::make_ref_counted<StorageNode>(std::move(leaf), std::move(value)); +} + +} // namespace + +EnvironmentFactory::EnvironmentFactory(const Environment& env) + : leaf_(env.storage_), + field_trials_(env.field_trials_), + clock_(env.clock_), + task_queue_factory_(env.task_queue_factory_), + event_log_(env.event_log_) {} + +void EnvironmentFactory::Set( + absl::Nullable<std::unique_ptr<const FieldTrialsView>> utility) { + if (utility != nullptr) { + field_trials_ = utility.get(); + Store(std::move(utility), leaf_); + } +} + +void EnvironmentFactory::Set(absl::Nullable<std::unique_ptr<Clock>> utility) { + if (utility != nullptr) { + clock_ = utility.get(); + Store(std::move(utility), leaf_); + } +} + +void EnvironmentFactory::Set( + absl::Nullable<std::unique_ptr<TaskQueueFactory>> utility) { + if (utility != nullptr) { + task_queue_factory_ = utility.get(); + Store(std::move(utility), leaf_); + } +} + +void EnvironmentFactory::Set( + absl::Nullable<std::unique_ptr<RtcEventLog>> utility) { + if (utility != nullptr) { + event_log_ = utility.get(); + Store(std::move(utility), leaf_); + } +} + +Environment EnvironmentFactory::CreateWithDefaults() && { + if (field_trials_ == nullptr) { + Set(std::make_unique<FieldTrialBasedConfig>()); + } + if (clock_ == nullptr) { + Set(Clock::GetRealTimeClock()); + } + if (task_queue_factory_ == nullptr) { + Set(CreateDefaultTaskQueueFactory(field_trials_)); + } + if (event_log_ == nullptr) { + Set(std::make_unique<RtcEventLogNull>()); + } + + RTC_DCHECK(field_trials_ != nullptr); + RTC_DCHECK(clock_ != nullptr); + RTC_DCHECK(task_queue_factory_ != nullptr); + RTC_DCHECK(event_log_ != nullptr); + return Environment(std::move(leaf_), // + field_trials_, clock_, task_queue_factory_, event_log_); +} + +Environment EnvironmentFactory::Create() const { + // Create a temporary copy to avoid mutating `this` with default utilities. + return EnvironmentFactory(*this).CreateWithDefaults(); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/api/environment/environment_factory.h b/third_party/libwebrtc/api/environment/environment_factory.h new file mode 100644 index 0000000000..a0fc3effdb --- /dev/null +++ b/third_party/libwebrtc/api/environment/environment_factory.h @@ -0,0 +1,148 @@ +/* + * Copyright 2023 The WebRTC Project Authors. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef API_ENVIRONMENT_ENVIRONMENT_FACTORY_H_ +#define API_ENVIRONMENT_ENVIRONMENT_FACTORY_H_ + +#include <memory> +#include <utility> + +#include "absl/base/nullability.h" +#include "api/environment/environment.h" +#include "api/ref_counted_base.h" +#include "api/scoped_refptr.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +// These classes are forward declared to reduce amount of headers exposed +// through api header. +class Clock; +class TaskQueueFactory; +class FieldTrialsView; +class RtcEventLog; + +// Constructs `Environment`. +// Individual utilities are provided using one of the `Set` functions. +// `Set` functions do nothing when nullptr value is passed. +// Creates default implementations for utilities that are not provided. +// +// Examples: +// Environment default_env = EnvironmentFactory().Create(); +// +// EnvironmentFactory factory; +// factory.Set(std::make_unique<CustomTaskQueueFactory>()); +// factory.Set(std::make_unique<CustomFieldTrials>()); +// Environment custom_env = factory.Create(); +// +class RTC_EXPORT EnvironmentFactory final { + public: + EnvironmentFactory() = default; + explicit EnvironmentFactory(const Environment& env); + + EnvironmentFactory(const EnvironmentFactory&) = default; + EnvironmentFactory(EnvironmentFactory&&) = default; + EnvironmentFactory& operator=(const EnvironmentFactory&) = default; + EnvironmentFactory& operator=(EnvironmentFactory&&) = default; + + ~EnvironmentFactory() = default; + + void Set(absl::Nullable<std::unique_ptr<const FieldTrialsView>> utility); + void Set(absl::Nullable<std::unique_ptr<Clock>> utility); + void Set(absl::Nullable<std::unique_ptr<TaskQueueFactory>> utility); + void Set(absl::Nullable<std::unique_ptr<RtcEventLog>> utility); + + void Set(absl::Nullable<const FieldTrialsView*> utility); + void Set(absl::Nullable<Clock*> utility); + void Set(absl::Nullable<TaskQueueFactory*> utility); + void Set(absl::Nullable<RtcEventLog*> utility); + + Environment Create() const; + + private: + Environment CreateWithDefaults() &&; + + scoped_refptr<const rtc::RefCountedBase> leaf_; + + absl::Nullable<const FieldTrialsView*> field_trials_ = nullptr; + absl::Nullable<Clock*> clock_ = nullptr; + absl::Nullable<TaskQueueFactory*> task_queue_factory_ = nullptr; + absl::Nullable<RtcEventLog*> event_log_ = nullptr; +}; + +// Helper for concise way to create an environment. +// `Environment env = CreateEnvironment(utility1, utility2)` is a shortcut to +// `EnvironmentFactory factory; +// factory.Set(utility1); +// factory.Set(utility2); +// Environment env = factory.Create();` +// +// Examples: +// Environment default_env = CreateEnvironment(); +// Environment custom_env = +// CreateEnvironment(std::make_unique<CustomTaskQueueFactory>(), +// std::make_unique<CustomFieldTrials>()); +template <typename... Utilities> +Environment CreateEnvironment(Utilities&&... utilities); + +//------------------------------------------------------------------------------ +// Implementation details follow +//------------------------------------------------------------------------------ + +inline void EnvironmentFactory::Set( + absl::Nullable<const FieldTrialsView*> utility) { + if (utility != nullptr) { + field_trials_ = utility; + } +} + +inline void EnvironmentFactory::Set(absl::Nullable<Clock*> utility) { + if (utility != nullptr) { + clock_ = utility; + } +} + +inline void EnvironmentFactory::Set(absl::Nullable<TaskQueueFactory*> utility) { + if (utility != nullptr) { + task_queue_factory_ = utility; + } +} + +inline void EnvironmentFactory::Set(absl::Nullable<RtcEventLog*> utility) { + if (utility != nullptr) { + event_log_ = utility; + } +} + +namespace webrtc_create_environment_internal { + +inline void Set(EnvironmentFactory& factory) {} + +template <typename FirstUtility, typename... Utilities> +void Set(EnvironmentFactory& factory, + FirstUtility&& first, + Utilities&&... utilities) { + factory.Set(std::forward<FirstUtility>(first)); + Set(factory, std::forward<Utilities>(utilities)...); +} + +} // namespace webrtc_create_environment_internal + +template <typename... Utilities> +Environment CreateEnvironment(Utilities&&... utilities) { + EnvironmentFactory factory; + webrtc_create_environment_internal::Set( + factory, std::forward<Utilities>(utilities)...); + return factory.Create(); +} + +} // namespace webrtc + +#endif // API_ENVIRONMENT_ENVIRONMENT_FACTORY_H_ diff --git a/third_party/libwebrtc/api/environment/environment_gn/moz.build b/third_party/libwebrtc/api/environment/environment_gn/moz.build new file mode 100644 index 0000000000..e7105ff573 --- /dev/null +++ b/third_party/libwebrtc/api/environment/environment_gn/moz.build @@ -0,0 +1,198 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + + + ### This moz.build was AUTOMATICALLY GENERATED from a GN config, ### + ### DO NOT edit it by hand. ### + +COMPILE_FLAGS["OS_INCLUDES"] = [] +AllowCompilerWarnings() + +DEFINES["ABSL_ALLOCATOR_NOTHROW"] = "1" +DEFINES["RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY"] = True +DEFINES["RTC_ENABLE_VP9"] = True +DEFINES["WEBRTC_ENABLE_PROTOBUF"] = "0" +DEFINES["WEBRTC_LIBRARY_IMPL"] = True +DEFINES["WEBRTC_MOZILLA_BUILD"] = True +DEFINES["WEBRTC_NON_STATIC_TRACE_EVENT_HANDLERS"] = "0" +DEFINES["WEBRTC_STRICT_FIELD_TRIALS"] = "0" + +FINAL_LIBRARY = "webrtc" + + +LOCAL_INCLUDES += [ + "!/ipc/ipdl/_ipdlheaders", + "!/third_party/libwebrtc/gen", + "/ipc/chromium/src", + "/third_party/libwebrtc/", + "/third_party/libwebrtc/third_party/abseil-cpp/", + "/tools/profiler/public" +] + +if not CONFIG["MOZ_DEBUG"]: + + DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "0" + DEFINES["NDEBUG"] = True + DEFINES["NVALGRIND"] = True + +if CONFIG["MOZ_DEBUG"] == "1": + + DEFINES["DYNAMIC_ANNOTATIONS_ENABLED"] = "1" + +if CONFIG["OS_TARGET"] == "Android": + + DEFINES["ANDROID"] = True + DEFINES["ANDROID_NDK_VERSION_ROLL"] = "r22_1" + DEFINES["HAVE_SYS_UIO_H"] = True + DEFINES["WEBRTC_ANDROID"] = True + DEFINES["WEBRTC_ANDROID_OPENSLES"] = True + DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True + DEFINES["WEBRTC_LINUX"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_GNU_SOURCE"] = True + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + +if CONFIG["OS_TARGET"] == "Darwin": + + DEFINES["WEBRTC_MAC"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_LIBCPP_HAS_NO_ALIGNED_ALLOCATION"] = True + DEFINES["__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES"] = "0" + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + +if CONFIG["OS_TARGET"] == "Linux": + + DEFINES["USE_AURA"] = "1" + DEFINES["USE_GLIB"] = "1" + DEFINES["USE_NSS_CERTS"] = "1" + DEFINES["USE_OZONE"] = "1" + DEFINES["USE_UDEV"] = True + DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True + DEFINES["WEBRTC_LINUX"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_FILE_OFFSET_BITS"] = "64" + DEFINES["_LARGEFILE64_SOURCE"] = True + DEFINES["_LARGEFILE_SOURCE"] = True + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + +if CONFIG["OS_TARGET"] == "OpenBSD": + + DEFINES["USE_GLIB"] = "1" + DEFINES["USE_OZONE"] = "1" + DEFINES["USE_X11"] = "1" + DEFINES["WEBRTC_BSD"] = True + DEFINES["WEBRTC_ENABLE_LIBEVENT"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_FILE_OFFSET_BITS"] = "64" + DEFINES["_LARGEFILE64_SOURCE"] = True + DEFINES["_LARGEFILE_SOURCE"] = True + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + +if CONFIG["OS_TARGET"] == "WINNT": + + DEFINES["CERT_CHAIN_PARA_HAS_EXTRA_FIELDS"] = True + DEFINES["NOMINMAX"] = True + DEFINES["NTDDI_VERSION"] = "0x0A000000" + DEFINES["PSAPI_VERSION"] = "2" + DEFINES["RTC_ENABLE_WIN_WGC"] = True + DEFINES["UNICODE"] = True + DEFINES["USE_AURA"] = "1" + DEFINES["WEBRTC_WIN"] = True + DEFINES["WIN32"] = True + DEFINES["WIN32_LEAN_AND_MEAN"] = True + DEFINES["WINAPI_FAMILY"] = "WINAPI_FAMILY_DESKTOP_APP" + DEFINES["WINVER"] = "0x0A00" + DEFINES["_ATL_NO_OPENGL"] = True + DEFINES["_CRT_RAND_S"] = True + DEFINES["_CRT_SECURE_NO_DEPRECATE"] = True + DEFINES["_ENABLE_EXTENDED_ALIGNED_STORAGE"] = True + DEFINES["_HAS_EXCEPTIONS"] = "0" + DEFINES["_HAS_NODISCARD"] = True + DEFINES["_SCL_SECURE_NO_DEPRECATE"] = True + DEFINES["_SECURE_ATL"] = True + DEFINES["_UNICODE"] = True + DEFINES["_WIN32_WINNT"] = "0x0A00" + DEFINES["_WINDOWS"] = True + DEFINES["__STD_C"] = True + +if CONFIG["TARGET_CPU"] == "aarch64": + + DEFINES["WEBRTC_ARCH_ARM64"] = True + DEFINES["WEBRTC_HAS_NEON"] = True + +if CONFIG["TARGET_CPU"] == "arm": + + DEFINES["WEBRTC_ARCH_ARM"] = True + DEFINES["WEBRTC_ARCH_ARM_V7"] = True + DEFINES["WEBRTC_HAS_NEON"] = True + +if CONFIG["TARGET_CPU"] == "mips32": + + DEFINES["MIPS32_LE"] = True + DEFINES["MIPS_FPU_LE"] = True + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["TARGET_CPU"] == "mips64": + + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["TARGET_CPU"] == "x86": + + DEFINES["WEBRTC_ENABLE_AVX2"] = True + +if CONFIG["TARGET_CPU"] == "x86_64": + + DEFINES["WEBRTC_ENABLE_AVX2"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Android": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Darwin": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "Linux": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "OpenBSD": + + DEFINES["_DEBUG"] = True + +if CONFIG["MOZ_DEBUG"] == "1" and CONFIG["OS_TARGET"] == "WINNT": + + DEFINES["_HAS_ITERATOR_DEBUGGING"] = "0" + +if CONFIG["MOZ_X11"] == "1" and CONFIG["OS_TARGET"] == "Linux": + + DEFINES["USE_X11"] = "1" + +if CONFIG["OS_TARGET"] == "Android" and CONFIG["TARGET_CPU"] == "arm": + + OS_LIBS += [ + "unwind" + ] + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "aarch64": + + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "arm": + + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86": + + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["OS_TARGET"] == "Linux" and CONFIG["TARGET_CPU"] == "x86_64": + + DEFINES["_GNU_SOURCE"] = True + +Library("environment_gn") diff --git a/third_party/libwebrtc/api/environment/environment_unittest.cc b/third_party/libwebrtc/api/environment/environment_unittest.cc new file mode 100644 index 0000000000..07bd8793bc --- /dev/null +++ b/third_party/libwebrtc/api/environment/environment_unittest.cc @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2023 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "api/environment/environment.h" + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "absl/functional/any_invocable.h" +#include "absl/types/optional.h" +#include "api/environment/environment_factory.h" +#include "api/field_trials_view.h" +#include "api/rtc_event_log/rtc_event_log.h" +#include "api/task_queue/task_queue_factory.h" +#include "api/units/timestamp.h" +#include "system_wrappers/include/clock.h" +#include "test/gmock.h" +#include "test/gtest.h" + +namespace webrtc { +namespace { + +using ::testing::ElementsAre; +using ::testing::IsEmpty; +using ::testing::Not; +using ::testing::NotNull; +using ::testing::Ref; + +class FakeEvent : public RtcEvent { + public: + Type GetType() const override { return RtcEvent::Type::FakeEvent; } + bool IsConfigEvent() const override { return false; } +}; + +class FakeFieldTrials : public FieldTrialsView { + public: + explicit FakeFieldTrials(absl::AnyInvocable<void() &&> on_destroyed = nullptr) + : on_destroyed_(std::move(on_destroyed)) {} + ~FakeFieldTrials() override { + if (on_destroyed_ != nullptr) { + std::move(on_destroyed_)(); + } + } + + std::string Lookup(absl::string_view key) const override { return "fake"; } + + private: + absl::AnyInvocable<void() &&> on_destroyed_; +}; + +class FakeTaskQueueFactory : public TaskQueueFactory { + public: + explicit FakeTaskQueueFactory( + absl::AnyInvocable<void() &&> on_destroyed = nullptr) + : on_destroyed_(std::move(on_destroyed)) {} + ~FakeTaskQueueFactory() override { + if (on_destroyed_ != nullptr) { + std::move(on_destroyed_)(); + } + } + + std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue( + absl::string_view name, + Priority priority) const override { + return nullptr; + } + + private: + absl::AnyInvocable<void() &&> on_destroyed_; +}; + +TEST(EnvironmentTest, DefaultEnvironmentHasAllUtilities) { + Environment env = EnvironmentFactory().Create(); + + // Try to use each utility, expect no crashes. + env.clock().CurrentTime(); + EXPECT_THAT(env.task_queue_factory().CreateTaskQueue( + "test", TaskQueueFactory::Priority::NORMAL), + NotNull()); + env.event_log().Log(std::make_unique<FakeEvent>()); + env.field_trials().Lookup("WebRTC-Debugging-RtpDump"); +} + +TEST(EnvironmentTest, UsesProvidedUtilitiesWithOwnership) { + auto owned_field_trials = std::make_unique<FakeFieldTrials>(); + auto owned_task_queue_factory = std::make_unique<FakeTaskQueueFactory>(); + auto owned_clock = std::make_unique<SimulatedClock>(Timestamp::Zero()); + auto owned_event_log = std::make_unique<RtcEventLogNull>(); + + FieldTrialsView& field_trials = *owned_field_trials; + TaskQueueFactory& task_queue_factory = *owned_task_queue_factory; + Clock& clock = *owned_clock; + RtcEventLog& event_log = *owned_event_log; + + Environment env = CreateEnvironment( + std::move(owned_field_trials), std::move(owned_clock), + std::move(owned_task_queue_factory), std::move(owned_event_log)); + + EXPECT_THAT(env.field_trials(), Ref(field_trials)); + EXPECT_THAT(env.task_queue_factory(), Ref(task_queue_factory)); + EXPECT_THAT(env.clock(), Ref(clock)); + EXPECT_THAT(env.event_log(), Ref(event_log)); +} + +TEST(EnvironmentTest, UsesProvidedUtilitiesWithoutOwnership) { + FakeFieldTrials field_trials; + FakeTaskQueueFactory task_queue_factory; + SimulatedClock clock(Timestamp::Zero()); + RtcEventLogNull event_log; + + Environment env = + CreateEnvironment(&field_trials, &clock, &task_queue_factory, &event_log); + + EXPECT_THAT(env.field_trials(), Ref(field_trials)); + EXPECT_THAT(env.task_queue_factory(), Ref(task_queue_factory)); + EXPECT_THAT(env.clock(), Ref(clock)); + EXPECT_THAT(env.event_log(), Ref(event_log)); +} + +TEST(EnvironmentTest, UsesLastProvidedUtility) { + auto owned_field_trials1 = std::make_unique<FakeFieldTrials>(); + auto owned_field_trials2 = std::make_unique<FakeFieldTrials>(); + FieldTrialsView& field_trials2 = *owned_field_trials2; + + Environment env = CreateEnvironment(std::move(owned_field_trials1), + std::move(owned_field_trials2)); + + EXPECT_THAT(env.field_trials(), Ref(field_trials2)); +} + +// Utilities can be provided from different sources, and when some source +// choose not to provide an utility, it is usually expressed with nullptr. +// When utility is not provided, it is natural to use previously set one. +// E.g. Both PeerConnectionFactoryDependencies and PeerConnectionDependencies +// provide field trials. When PeerConnectionDependencies::trials == nullptr, +// then trials from the PeerConnectionFactoryDependencies should be used. +// With nullptr accepted and ignored this can be expressed by +// `Environemt env = CreateEnvironment(pcf_deps.trials, pc_deps.trials);` +// That would use pc_deps.trials when not nullptr, pcf_deps.trials when +// pc_deps.trials is nullptr, but pcf_deps.trials is not, and default field +// trials when both are nullptr. +TEST(EnvironmentTest, IgnoresProvidedNullptrUtility) { + auto owned_field_trials = std::make_unique<FakeFieldTrials>(); + std::unique_ptr<FieldTrialsView> null_field_trials = nullptr; + FieldTrialsView& field_trials = *owned_field_trials; + + Environment env = CreateEnvironment(std::move(owned_field_trials), + std::move(null_field_trials)); + + EXPECT_THAT(env.field_trials(), Ref(field_trials)); +} + +TEST(EnvironmentTest, KeepsUtilityAliveWhileEnvironmentIsAlive) { + bool utility_destroyed = false; + auto field_trials = std::make_unique<FakeFieldTrials>( + /*on_destroyed=*/[&] { utility_destroyed = true; }); + + // Wrap Environment into optional to have explicit control when it is deleted. + absl::optional<Environment> env = CreateEnvironment(std::move(field_trials)); + + EXPECT_FALSE(utility_destroyed); + env = absl::nullopt; + EXPECT_TRUE(utility_destroyed); +} + +TEST(EnvironmentTest, KeepsUtilityAliveWhileCopyOfEnvironmentIsAlive) { + bool utility_destroyed = false; + auto field_trials = std::make_unique<FakeFieldTrials>( + /*on_destroyed=*/[&] { utility_destroyed = true; }); + + absl::optional<Environment> env1 = CreateEnvironment(std::move(field_trials)); + absl::optional<Environment> env2 = env1; + + EXPECT_FALSE(utility_destroyed); + env1 = absl::nullopt; + EXPECT_FALSE(utility_destroyed); + env2 = absl::nullopt; + EXPECT_TRUE(utility_destroyed); +} + +TEST(EnvironmentTest, FactoryCanBeReusedToCreateDifferentEnvironments) { + auto owned_task_queue_factory = std::make_unique<FakeTaskQueueFactory>(); + auto owned_field_trials1 = std::make_unique<FakeFieldTrials>(); + auto owned_field_trials2 = std::make_unique<FakeFieldTrials>(); + TaskQueueFactory& task_queue_factory = *owned_task_queue_factory; + FieldTrialsView& field_trials1 = *owned_field_trials1; + FieldTrialsView& field_trials2 = *owned_field_trials2; + + EnvironmentFactory factory; + factory.Set(std::move(owned_task_queue_factory)); + factory.Set(std::move(owned_field_trials1)); + Environment env1 = factory.Create(); + factory.Set(std::move(owned_field_trials2)); + Environment env2 = factory.Create(); + + // Environments share the same custom task queue factory. + EXPECT_THAT(env1.task_queue_factory(), Ref(task_queue_factory)); + EXPECT_THAT(env2.task_queue_factory(), Ref(task_queue_factory)); + + // Environments have different field trials. + EXPECT_THAT(env1.field_trials(), Ref(field_trials1)); + EXPECT_THAT(env2.field_trials(), Ref(field_trials2)); +} + +TEST(EnvironmentTest, FactoryCanCreateNewEnvironmentFromExistingOne) { + Environment env1 = + CreateEnvironment(std::make_unique<FakeTaskQueueFactory>()); + EnvironmentFactory factory(env1); + factory.Set(std::make_unique<FakeFieldTrials>()); + Environment env2 = factory.Create(); + + // Environments share the same default clock. + EXPECT_THAT(env2.clock(), Ref(env1.clock())); + + // Environments share the same custom task queue factory. + EXPECT_THAT(env2.task_queue_factory(), Ref(env1.task_queue_factory())); + + // Environments have different field trials. + EXPECT_THAT(env2.field_trials(), Not(Ref(env1.field_trials()))); +} + +TEST(EnvironmentTest, KeepsOwnershipsWhenCreateNewEnvironmentFromExistingOne) { + bool utility1_destroyed = false; + bool utility2_destroyed = false; + absl::optional<Environment> env1 = + CreateEnvironment(std::make_unique<FakeTaskQueueFactory>( + /*on_destroyed=*/[&] { utility1_destroyed = true; })); + + absl::optional<EnvironmentFactory> factory = EnvironmentFactory(*env1); + + // Destroy env1, check utility1 it was using is still alive. + env1 = absl::nullopt; + EXPECT_FALSE(utility1_destroyed); + + factory->Set(std::make_unique<FakeFieldTrials>( + /*on_destroyed=*/[&] { utility2_destroyed = true; })); + absl::optional<Environment> env2 = factory->Create(); + + // Destroy the factory, check all utilities used by env2 are alive. + factory = absl::nullopt; + EXPECT_FALSE(utility1_destroyed); + EXPECT_FALSE(utility2_destroyed); + + // Once last Environment object is deleted, utilties should be deleted too. + env2 = absl::nullopt; + EXPECT_TRUE(utility1_destroyed); + EXPECT_TRUE(utility2_destroyed); +} + +TEST(EnvironmentTest, DestroysUtilitiesInReverseProvidedOrder) { + std::vector<std::string> destroyed; + auto field_trials = std::make_unique<FakeFieldTrials>( + /*on_destroyed=*/[&] { destroyed.push_back("field_trials"); }); + auto task_queue_factory = std::make_unique<FakeTaskQueueFactory>( + /*on_destroyed=*/[&] { destroyed.push_back("task_queue_factory"); }); + + absl::optional<Environment> env = + CreateEnvironment(std::move(field_trials), std::move(task_queue_factory)); + + ASSERT_THAT(destroyed, IsEmpty()); + env = absl::nullopt; + EXPECT_THAT(destroyed, ElementsAre("task_queue_factory", "field_trials")); +} + +} // namespace +} // namespace webrtc |