Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
63
TMessagesProj/jni/voip/webrtc/api/environment/BUILD.gn
Normal file
63
TMessagesProj/jni/voip/webrtc/api/environment/BUILD.gn
Normal file
|
|
@ -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",
|
||||
]
|
||||
}
|
||||
}
|
||||
15
TMessagesProj/jni/voip/webrtc/api/environment/OWNERS
Normal file
15
TMessagesProj/jni/voip/webrtc/api/environment/OWNERS
Normal file
|
|
@ -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
|
||||
148
TMessagesProj/jni/voip/webrtc/api/environment/environment.h
Normal file
148
TMessagesProj/jni/voip/webrtc/api/environment/environment.h
Normal file
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
|
|
@ -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_
|
||||
|
|
@ -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
|
||||
Loading…
Add table
Add a link
Reference in a new issue