diff options
Diffstat (limited to '')
13 files changed, 947 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/rtc_event_log/BUILD.gn b/third_party/libwebrtc/api/rtc_event_log/BUILD.gn new file mode 100644 index 0000000000..158dc06a7b --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/BUILD.gn @@ -0,0 +1,48 @@ +# Copyright (c) 2019 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_library("rtc_event_log") { + visibility = [ "*" ] + sources = [ + "rtc_event.cc", + "rtc_event.h", + "rtc_event_log.cc", + "rtc_event_log.h", + "rtc_event_log_factory_interface.h", + ] + + deps = [ + "..:libjingle_logging_api", + "../../rtc_base:checks", + "../../rtc_base:timeutils", + "../task_queue", + ] +} + +rtc_library("rtc_event_log_factory") { + visibility = [ "*" ] + sources = [ + "rtc_event_log_factory.cc", + "rtc_event_log_factory.h", + ] + + deps = [ + ":rtc_event_log", + "../../rtc_base:checks", + "../../rtc_base/system:rtc_export", + "../../system_wrappers:field_trial", + "../task_queue", + ] + + if (rtc_enable_protobuf) { + defines = [ "WEBRTC_ENABLE_RTC_EVENT_LOG" ] + deps += [ "../../logging:rtc_event_log_impl" ] + } +} diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event.cc b/third_party/libwebrtc/api/rtc_event_log/rtc_event.cc new file mode 100644 index 0000000000..631188b915 --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event.cc @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2019 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/rtc_event_log/rtc_event.h" + +#include "rtc_base/time_utils.h" + +namespace webrtc { + +RtcEvent::RtcEvent() : timestamp_us_(rtc::TimeMillis() * 1000) {} + +} // namespace webrtc diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event.h b/third_party/libwebrtc/api/rtc_event_log/rtc_event.h new file mode 100644 index 0000000000..aa74944fe5 --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2017 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_RTC_EVENT_LOG_RTC_EVENT_H_ +#define API_RTC_EVENT_LOG_RTC_EVENT_H_ + +#include <cstdint> + +namespace webrtc { + +// This class allows us to store unencoded RTC events. Subclasses of this class +// store the actual information. This allows us to keep all unencoded events, +// even when their type and associated information differ, in the same buffer. +// Additionally, it prevents dependency leaking - a module that only logs +// events of type RtcEvent_A doesn't need to know about anything associated +// with events of type RtcEvent_B. +class RtcEvent { + public: + // Subclasses of this class have to associate themselves with a unique value + // of Type. This leaks the information of existing subclasses into the + // superclass, but the *actual* information - rtclog::StreamConfig, etc. - + // is kept separate. + enum class Type : uint32_t { + AlrStateEvent, + RouteChangeEvent, + RemoteEstimateEvent, + AudioNetworkAdaptation, + AudioPlayout, + AudioReceiveStreamConfig, + AudioSendStreamConfig, + BweUpdateDelayBased, + BweUpdateLossBased, + DtlsTransportState, + DtlsWritableState, + IceCandidatePairConfig, + IceCandidatePairEvent, + ProbeClusterCreated, + ProbeResultFailure, + ProbeResultSuccess, + RtcpPacketIncoming, + RtcpPacketOutgoing, + RtpPacketIncoming, + RtpPacketOutgoing, + VideoReceiveStreamConfig, + VideoSendStreamConfig, + GenericPacketSent, + GenericPacketReceived, + GenericAckReceived, + FrameDecoded, + NetEqSetMinimumDelay, + BeginV3Log = 0x2501580, + EndV3Log = 0x2501581, + FakeEvent, // For unit testing. + }; + + RtcEvent(); + virtual ~RtcEvent() = default; + + virtual Type GetType() const = 0; + + virtual bool IsConfigEvent() const = 0; + + // Events are grouped by Type before being encoded. + // Optionally, `GetGroupKey` can be overloaded to group the + // events by a secondary key (in addition to the event type.) + // This can, in some cases, improve compression efficiency + // e.g. by grouping events by SSRC. + virtual uint32_t GetGroupKey() const { return 0; } + + int64_t timestamp_ms() const { return timestamp_us_ / 1000; } + int64_t timestamp_us() const { return timestamp_us_; } + + protected: + explicit RtcEvent(int64_t timestamp_us) : timestamp_us_(timestamp_us) {} + + const int64_t timestamp_us_; +}; + +} // namespace webrtc + +#endif // API_RTC_EVENT_LOG_RTC_EVENT_H_ diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc new file mode 100644 index 0000000000..56189c0ff7 --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2018 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/rtc_event_log/rtc_event_log.h" + +namespace webrtc { + +bool RtcEventLogNull::StartLogging( + std::unique_ptr<RtcEventLogOutput> /*output*/, + int64_t /*output_period_ms*/) { + return false; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.h b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.h new file mode 100644 index 0000000000..7b42cdc028 --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2015 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_RTC_EVENT_LOG_RTC_EVENT_LOG_H_ +#define API_RTC_EVENT_LOG_RTC_EVENT_LOG_H_ + +#include <cstddef> +#include <cstdint> +#include <functional> +#include <memory> + +#include "api/rtc_event_log/rtc_event.h" +#include "api/rtc_event_log_output.h" +#include "api/task_queue/task_queue_factory.h" + +namespace webrtc { + +class RtcEventLog { + public: + enum : size_t { kUnlimitedOutput = 0 }; + enum : int64_t { kImmediateOutput = 0 }; + + // TODO(eladalon): Get rid of the legacy encoding and this enum once all + // clients have migrated to the new format. + enum class EncodingType { Legacy, NewFormat, ProtoFree }; + + virtual ~RtcEventLog() = default; + + // Starts logging to a given output. The output might be limited in size, + // and may close itself once it has reached the maximum size. + virtual bool StartLogging(std::unique_ptr<RtcEventLogOutput> output, + int64_t output_period_ms) = 0; + + // Stops logging to file and waits until the file has been closed, after + // which it would be permissible to read and/or modify it. + virtual void StopLogging() = 0; + + // Stops logging to file and calls `callback` when the file has been closed. + // Note that it is not safe to call any other members, including the + // destructor, until the callback has been called. + // TODO(srte): Remove default implementation when it's safe to do so. + virtual void StopLogging(std::function<void()> callback) { + StopLogging(); + callback(); + } + + // Log an RTC event (the type of event is determined by the subclass). + virtual void Log(std::unique_ptr<RtcEvent> event) = 0; +}; + +// No-op implementation is used if flag is not set, or in tests. +class RtcEventLogNull final : public RtcEventLog { + public: + bool StartLogging(std::unique_ptr<RtcEventLogOutput> output, + int64_t output_period_ms) override; + void StopLogging() override {} + void Log(std::unique_ptr<RtcEvent> event) override {} +}; + +} // namespace webrtc + +#endif // API_RTC_EVENT_LOG_RTC_EVENT_LOG_H_ diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.cc b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.cc new file mode 100644 index 0000000000..a3cb68cf54 --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.cc @@ -0,0 +1,48 @@ +/* + * Copyright 2017 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/rtc_event_log/rtc_event_log_factory.h" + +#include <memory> +#include <utility> + +#include "rtc_base/checks.h" +#include "system_wrappers/include/field_trial.h" + +#ifdef WEBRTC_ENABLE_RTC_EVENT_LOG +#include "logging/rtc_event_log/rtc_event_log_impl.h" +#endif + +namespace webrtc { + +RtcEventLogFactory::RtcEventLogFactory(TaskQueueFactory* task_queue_factory) + : task_queue_factory_(task_queue_factory) { + RTC_DCHECK(task_queue_factory_); +} + +std::unique_ptr<RtcEventLog> RtcEventLogFactory::Create( + RtcEventLog::EncodingType encoding_type) const { +#ifdef WEBRTC_ENABLE_RTC_EVENT_LOG + if (field_trial::IsEnabled("WebRTC-RtcEventLogKillSwitch")) { + return std::make_unique<RtcEventLogNull>(); + } + return std::make_unique<RtcEventLogImpl>( + RtcEventLogImpl::CreateEncoder(encoding_type), task_queue_factory_); +#else + return std::make_unique<RtcEventLogNull>(); +#endif +} + +std::unique_ptr<RtcEventLog> RtcEventLogFactory::CreateRtcEventLog( + RtcEventLog::EncodingType encoding_type) { + return Create(encoding_type); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.h b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.h new file mode 100644 index 0000000000..fd1db3c728 --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 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_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_H_ +#define API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_H_ + +#include <memory> + +#include "api/rtc_event_log/rtc_event_log.h" +#include "api/rtc_event_log/rtc_event_log_factory_interface.h" +#include "api/task_queue/task_queue_factory.h" +#include "rtc_base/system/rtc_export.h" + +namespace webrtc { + +class RTC_EXPORT RtcEventLogFactory : public RtcEventLogFactoryInterface { + public: + explicit RtcEventLogFactory(TaskQueueFactory* task_queue_factory); + ~RtcEventLogFactory() override {} + + std::unique_ptr<RtcEventLog> Create( + RtcEventLog::EncodingType encoding_type) const override; + std::unique_ptr<RtcEventLog> CreateRtcEventLog( + RtcEventLog::EncodingType encoding_type) override; + + private: + TaskQueueFactory* const task_queue_factory_; +}; + +} // namespace webrtc + +#endif // API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_H_ diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory_interface.h b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory_interface.h new file mode 100644 index 0000000000..a6f4dee92f --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_factory_interface.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 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_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_INTERFACE_H_ +#define API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_INTERFACE_H_ + +#include <memory> + +#include "api/rtc_event_log/rtc_event_log.h" + +namespace webrtc { + +// This interface exists to allow webrtc to be optionally built without +// RtcEventLog support. A PeerConnectionFactory is constructed with an +// RtcEventLogFactoryInterface, which may or may not be null. +class RtcEventLogFactoryInterface { + public: + virtual ~RtcEventLogFactoryInterface() = default; + + virtual std::unique_ptr<RtcEventLog> Create( + RtcEventLog::EncodingType encoding_type) const = 0; + [[deprecated]] virtual std::unique_ptr<RtcEventLog> CreateRtcEventLog( + RtcEventLog::EncodingType encoding_type) = 0; +}; + +} // namespace webrtc + +#endif // API_RTC_EVENT_LOG_RTC_EVENT_LOG_FACTORY_INTERFACE_H_ diff --git a/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_gn/moz.build b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_gn/moz.build new file mode 100644 index 0000000000..a96be6791f --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log/rtc_event_log_gn/moz.build @@ -0,0 +1,226 @@ +# 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" +] + +UNIFIED_SOURCES += [ + "/third_party/libwebrtc/api/rtc_event_log/rtc_event.cc", + "/third_party/libwebrtc/api/rtc_event_log/rtc_event_log.cc" +] + +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_LINUX"] = True + DEFINES["WEBRTC_POSIX"] = True + DEFINES["_GNU_SOURCE"] = True + DEFINES["__STDC_CONSTANT_MACROS"] = True + DEFINES["__STDC_FORMAT_MACROS"] = True + + OS_LIBS += [ + "log" + ] + +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_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_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["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 + + OS_LIBS += [ + "winmm" + ] + +if CONFIG["CPU_ARCH"] == "aarch64": + + DEFINES["WEBRTC_ARCH_ARM64"] = True + DEFINES["WEBRTC_HAS_NEON"] = True + +if CONFIG["CPU_ARCH"] == "arm": + + CXXFLAGS += [ + "-mfpu=neon" + ] + + DEFINES["WEBRTC_ARCH_ARM"] = True + DEFINES["WEBRTC_ARCH_ARM_V7"] = True + DEFINES["WEBRTC_HAS_NEON"] = True + +if CONFIG["CPU_ARCH"] == "mips32": + + DEFINES["MIPS32_LE"] = True + DEFINES["MIPS_FPU_LE"] = True + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["CPU_ARCH"] == "mips64": + + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["CPU_ARCH"] == "x86": + + DEFINES["WEBRTC_ENABLE_AVX2"] = True + +if CONFIG["CPU_ARCH"] == "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["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Android": + + OS_LIBS += [ + "android_support", + "unwind" + ] + +if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Android": + + CXXFLAGS += [ + "-msse2" + ] + + OS_LIBS += [ + "android_support" + ] + +if CONFIG["CPU_ARCH"] == "aarch64" and CONFIG["OS_TARGET"] == "Linux": + + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["CPU_ARCH"] == "arm" and CONFIG["OS_TARGET"] == "Linux": + + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["CPU_ARCH"] == "x86" and CONFIG["OS_TARGET"] == "Linux": + + CXXFLAGS += [ + "-msse2" + ] + + DEFINES["_GNU_SOURCE"] = True + +if CONFIG["CPU_ARCH"] == "x86_64" and CONFIG["OS_TARGET"] == "Linux": + + DEFINES["_GNU_SOURCE"] = True + +Library("rtc_event_log_gn") diff --git a/third_party/libwebrtc/api/rtc_event_log_output.h b/third_party/libwebrtc/api/rtc_event_log_output.h new file mode 100644 index 0000000000..f1f84a5f3a --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log_output.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2017 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_RTC_EVENT_LOG_OUTPUT_H_ +#define API_RTC_EVENT_LOG_OUTPUT_H_ + +#include <string> + +#include "absl/strings/string_view.h" + +namespace webrtc { + +// NOTE: This class is still under development and may change without notice. +class RtcEventLogOutput { + public: + virtual ~RtcEventLogOutput() = default; + + // An output normally starts out active, though that might not always be + // the case (e.g. failed to open a file for writing). + // Once an output has become inactive (e.g. maximum file size reached), it can + // never become active again. + virtual bool IsActive() const = 0; + + // Write encoded events to an output. Returns true if the output was + // successfully written in its entirety. Otherwise, no guarantee is given + // about how much data was written, if any. The output sink becomes inactive + // after the first time `false` is returned. Write() may not be called on + // an inactive output sink. + virtual bool Write(absl::string_view output) = 0; + + // Indicates that buffers should be written to disk if applicable. + virtual void Flush() {} +}; + +} // namespace webrtc + +#endif // API_RTC_EVENT_LOG_OUTPUT_H_ diff --git a/third_party/libwebrtc/api/rtc_event_log_output_file.cc b/third_party/libwebrtc/api/rtc_event_log_output_file.cc new file mode 100644 index 0000000000..e1d4c7c711 --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log_output_file.cc @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2017 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/rtc_event_log_output_file.h" + +#include <limits> +#include <utility> + +#include "api/rtc_event_log/rtc_event_log.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { + +// Together with the assumption of no single Write() would ever be called on +// an input with length greater-than-or-equal-to (max(size_t) / 2), this +// guarantees no overflow of the check for remaining file capacity in Write(). +// This does *not* apply to files with unlimited size. +const size_t RtcEventLogOutputFile::kMaxReasonableFileSize = + std::numeric_limits<size_t>::max() / 2; + +RtcEventLogOutputFile::RtcEventLogOutputFile(const std::string& file_name) + : RtcEventLogOutputFile(FileWrapper::OpenWriteOnly(file_name), + RtcEventLog::kUnlimitedOutput) {} + +RtcEventLogOutputFile::RtcEventLogOutputFile(const std::string& file_name, + size_t max_size_bytes) + + // Unlike plain fopen, FileWrapper takes care of filename utf8 -> + // wchar conversion on Windows. + : RtcEventLogOutputFile(FileWrapper::OpenWriteOnly(file_name), + max_size_bytes) {} + +RtcEventLogOutputFile::RtcEventLogOutputFile(FILE* file, size_t max_size_bytes) + : RtcEventLogOutputFile(FileWrapper(file), max_size_bytes) {} + +RtcEventLogOutputFile::RtcEventLogOutputFile(FileWrapper file, + size_t max_size_bytes) + : max_size_bytes_(max_size_bytes), file_(std::move(file)) { + RTC_CHECK_LE(max_size_bytes_, kMaxReasonableFileSize); + if (!file_.is_open()) { + RTC_LOG(LS_ERROR) << "Invalid file. WebRTC event log not started."; + } +} + +bool RtcEventLogOutputFile::IsActive() const { + return IsActiveInternal(); +} + +bool RtcEventLogOutputFile::Write(absl::string_view output) { + RTC_DCHECK(IsActiveInternal()); + // No single write may be so big, that it would risk overflowing the + // calculation of (written_bytes_ + output.length()). + RTC_DCHECK_LT(output.size(), kMaxReasonableFileSize); + + if (max_size_bytes_ == RtcEventLog::kUnlimitedOutput || + written_bytes_ + output.size() <= max_size_bytes_) { + if (file_.Write(output.data(), output.size())) { + written_bytes_ += output.size(); + return true; + } else { + RTC_LOG(LS_ERROR) << "Write to WebRtcEventLog file failed."; + } + } else { + RTC_LOG(LS_VERBOSE) << "Max file size reached."; + } + + // Failed, for one of above reasons. Close output file. + file_.Close(); + return false; +} + +// Internal non-virtual method. +bool RtcEventLogOutputFile::IsActiveInternal() const { + return file_.is_open(); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/api/rtc_event_log_output_file.h b/third_party/libwebrtc/api/rtc_event_log_output_file.h new file mode 100644 index 0000000000..c9ae0a8ede --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log_output_file.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2017 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_RTC_EVENT_LOG_OUTPUT_FILE_H_ +#define API_RTC_EVENT_LOG_OUTPUT_FILE_H_ + +#include <stddef.h> +#include <stdio.h> + +#include <string> + +#include "api/rtc_event_log_output.h" +#include "rtc_base/system/file_wrapper.h" + +namespace webrtc { + +class RtcEventLogOutputFile final : public RtcEventLogOutput { + public: + static const size_t kMaxReasonableFileSize; // Explanation at declaration. + + // Unlimited/limited-size output file (by filename). + explicit RtcEventLogOutputFile(const std::string& file_name); + RtcEventLogOutputFile(const std::string& file_name, size_t max_size_bytes); + + // Limited-size output file (by FILE*). This class takes ownership + // of the FILE*, and closes it on destruction. + RtcEventLogOutputFile(FILE* file, size_t max_size_bytes); + + ~RtcEventLogOutputFile() override = default; + + bool IsActive() const override; + + bool Write(absl::string_view output) override; + + private: + RtcEventLogOutputFile(FileWrapper file, size_t max_size_bytes); + + // IsActive() can be called either from outside or from inside, but we don't + // want to incur the overhead of a virtual function call if called from inside + // some other function of this class. + inline bool IsActiveInternal() const; + + // Maximum size, or zero for no limit. + const size_t max_size_bytes_; + size_t written_bytes_{0}; + FileWrapper file_; +}; + +} // namespace webrtc + +#endif // API_RTC_EVENT_LOG_OUTPUT_FILE_H_ diff --git a/third_party/libwebrtc/api/rtc_event_log_output_file_unittest.cc b/third_party/libwebrtc/api/rtc_event_log_output_file_unittest.cc new file mode 100644 index 0000000000..0aff57fbbc --- /dev/null +++ b/third_party/libwebrtc/api/rtc_event_log_output_file_unittest.cc @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2017 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/rtc_event_log_output_file.h" + +#include <fstream> +#include <iterator> +#include <memory> +#include <string> + +#include "rtc_base/checks.h" +#include "test/gtest.h" +#include "test/testsupport/file_utils.h" + +namespace webrtc { + +class RtcEventLogOutputFileTest : public ::testing::Test { + public: + RtcEventLogOutputFileTest() : output_file_name_(GetOutputFilePath()) { + // Ensure no leftovers from previous runs, which might not have terminated + // in an orderly fashion. + remove(output_file_name_.c_str()); + } + + ~RtcEventLogOutputFileTest() override { remove(output_file_name_.c_str()); } + + protected: + std::string GetOutputFilePath() const { + auto test_info = ::testing::UnitTest::GetInstance()->current_test_info(); + return test::OutputPath() + test_info->test_case_name() + test_info->name(); + } + + std::string GetOutputFileContents() const { + std::ifstream file(output_file_name_, + std::ios_base::in | std::ios_base::binary); + RTC_CHECK(file.is_open()); + RTC_CHECK(file.good()); + std::string file_str((std::istreambuf_iterator<char>(file)), + std::istreambuf_iterator<char>()); + return file_str; + } + + const std::string output_file_name_; +}; + +TEST_F(RtcEventLogOutputFileTest, NonDefectiveOutputsStartOutActive) { + auto output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_); + EXPECT_TRUE(output_file->IsActive()); +} + +TEST_F(RtcEventLogOutputFileTest, DefectiveOutputsStartOutInactive) { + const std::string illegal_filename = "/////////"; + auto output_file = std::make_unique<RtcEventLogOutputFile>(illegal_filename); + EXPECT_FALSE(output_file->IsActive()); +} + +// Sanity over opening a file (by filename) with an unlimited size. +TEST_F(RtcEventLogOutputFileTest, UnlimitedOutputFile) { + const std::string output_str = "one two three"; + + auto output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_); + output_file->Write(output_str); + output_file.reset(); // Closing the file flushes the buffer to disk. + + EXPECT_EQ(GetOutputFileContents(), output_str); +} + +// Do not allow writing more bytes to the file than max file size. +TEST_F(RtcEventLogOutputFileTest, LimitedOutputFileCappedToCapacity) { + // Fit two bytes, then the third should be rejected. + auto output_file = + std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2); + + output_file->Write("1"); + output_file->Write("2"); + output_file->Write("3"); + // Unsuccessful writes close the file; no need to delete the output to flush. + + EXPECT_EQ(GetOutputFileContents(), "12"); +} + +// Make sure that calls to Write() either write everything to the file, or +// nothing (short of underlying issues in the module that handles the file, +// which would be beyond our control). +TEST_F(RtcEventLogOutputFileTest, DoNotWritePartialLines) { + const std::string output_str_1 = "0123456789"; + const std::string output_str_2 = "abcdefghij"; + + // Set a file size limit just shy of fitting the entire second line. + const size_t size_limit = output_str_1.length() + output_str_2.length() - 1; + auto output_file = + std::make_unique<RtcEventLogOutputFile>(output_file_name_, size_limit); + + output_file->Write(output_str_1); + output_file->Write(output_str_2); + // Unsuccessful writes close the file; no need to delete the output to flush. + + EXPECT_EQ(GetOutputFileContents(), output_str_1); +} + +TEST_F(RtcEventLogOutputFileTest, UnsuccessfulWriteReturnsFalse) { + auto output_file = + std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2); + EXPECT_FALSE(output_file->Write("abc")); +} + +TEST_F(RtcEventLogOutputFileTest, SuccessfulWriteReturnsTrue) { + auto output_file = + std::make_unique<RtcEventLogOutputFile>(output_file_name_, 3); + EXPECT_TRUE(output_file->Write("abc")); +} + +// Even if capacity is reached, a successful write leaves the output active. +TEST_F(RtcEventLogOutputFileTest, FileStillActiveAfterSuccessfulWrite) { + auto output_file = + std::make_unique<RtcEventLogOutputFile>(output_file_name_, 3); + ASSERT_TRUE(output_file->Write("abc")); + EXPECT_TRUE(output_file->IsActive()); +} + +// Unsuccessful writes switch the output to inactive, even if capacity has +// not yet been reached. +TEST_F(RtcEventLogOutputFileTest, FileInactiveAfterUnsuccessfulWrite) { + auto output_file = + std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2); + ASSERT_FALSE(output_file->Write("abc")); + EXPECT_FALSE(output_file->IsActive()); +} + +TEST_F(RtcEventLogOutputFileTest, AllowReasonableFileSizeLimits) { + auto output_file = std::make_unique<RtcEventLogOutputFile>( + output_file_name_, RtcEventLogOutputFile::kMaxReasonableFileSize); + EXPECT_TRUE(output_file->IsActive()); +} + +#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID) +class RtcEventLogOutputFileDeathTest : public RtcEventLogOutputFileTest {}; + +TEST_F(RtcEventLogOutputFileDeathTest, WritingToInactiveFileForbidden) { + RtcEventLogOutputFile output_file(output_file_name_, 2); + ASSERT_FALSE(output_file.Write("abc")); + ASSERT_FALSE(output_file.IsActive()); + EXPECT_DEATH(output_file.Write("abc"), ""); +} + +TEST_F(RtcEventLogOutputFileDeathTest, DisallowUnreasonableFileSizeLimits) { + // Keeping in a temporary unique_ptr to make it clearer that the death is + // triggered by construction, not destruction. + std::unique_ptr<RtcEventLogOutputFile> output_file; + auto create_output_file = [&] { + const size_t unreasonable_size = + RtcEventLogOutputFile::kMaxReasonableFileSize + 1; + output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_, + unreasonable_size); + }; + EXPECT_DEATH(create_output_file(), ""); +} +#endif + +} // namespace webrtc |