diff --git a/logging/BUILD.gn b/logging/BUILD.gn index 4d91b69404..ae38399024 100644 --- a/logging/BUILD.gn +++ b/logging/BUILD.gn @@ -232,6 +232,23 @@ rtc_static_library("rtc_event_log_impl_base") { } } +rtc_source_set("fake_rtc_event_log") { + testonly = true + sources = [ + "rtc_event_log/fake_rtc_event_log.cc", + "rtc_event_log/fake_rtc_event_log.h", + "rtc_event_log/fake_rtc_event_log_factory.cc", + "rtc_event_log/fake_rtc_event_log_factory.h", + ] + + deps = [ + ":ice_log", + ":rtc_event_log_api", + "../rtc_base:checks", + "../rtc_base:rtc_base", + ] +} + if (rtc_enable_protobuf) { proto_library("rtc_event_log_proto") { sources = [ diff --git a/logging/rtc_event_log/fake_rtc_event_log.cc b/logging/rtc_event_log/fake_rtc_event_log.cc new file mode 100644 index 0000000000..55f4b582c7 --- /dev/null +++ b/logging/rtc_event_log/fake_rtc_event_log.cc @@ -0,0 +1,41 @@ +/* + * 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 "logging/rtc_event_log/fake_rtc_event_log.h" + +#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h" +#include "rtc_base/bind.h" +#include "rtc_base/checks.h" +#include "rtc_base/logging.h" + +namespace webrtc { + +FakeRtcEventLog::FakeRtcEventLog(rtc::Thread* thread) : thread_(thread) { + RTC_DCHECK(thread_); +} +FakeRtcEventLog::~FakeRtcEventLog() = default; + +bool FakeRtcEventLog::StartLogging(std::unique_ptr output, + int64_t output_period_ms) { + return true; +} + +void FakeRtcEventLog::StopLogging() { + invoker_.Flush(thread_); +} + +void FakeRtcEventLog::Log(std::unique_ptr event) { + RtcEvent::Type rtc_event_type = event->GetType(); + invoker_.AsyncInvoke( + RTC_FROM_HERE, thread_, + rtc::Bind(&FakeRtcEventLog::IncrementEventCount, this, rtc_event_type)); +} + +} // namespace webrtc diff --git a/logging/rtc_event_log/fake_rtc_event_log.h b/logging/rtc_event_log/fake_rtc_event_log.h new file mode 100644 index 0000000000..c5ea08aa69 --- /dev/null +++ b/logging/rtc_event_log/fake_rtc_event_log.h @@ -0,0 +1,43 @@ +/* + * 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. + */ + +#ifndef LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_H_ +#define LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_H_ + +#include +#include + +#include "logging/rtc_event_log/events/rtc_event.h" +#include "logging/rtc_event_log/rtc_event_log.h" +#include "rtc_base/asyncinvoker.h" +#include "rtc_base/thread.h" + +namespace webrtc { + +class FakeRtcEventLog : public RtcEventLog { + public: + explicit FakeRtcEventLog(rtc::Thread* thread); + ~FakeRtcEventLog() override; + bool StartLogging(std::unique_ptr output, + int64_t output_period_ms) override; + void StopLogging() override; + void Log(std::unique_ptr event) override; + int GetEventCount(RtcEvent::Type event_type) { return count_[event_type]; } + + private: + void IncrementEventCount(RtcEvent::Type event_type) { ++count_[event_type]; } + std::map count_; + rtc::Thread* thread_; + rtc::AsyncInvoker invoker_; +}; + +} // namespace webrtc + +#endif // LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_H_ diff --git a/logging/rtc_event_log/fake_rtc_event_log_factory.cc b/logging/rtc_event_log/fake_rtc_event_log_factory.cc new file mode 100644 index 0000000000..b3f638cbb4 --- /dev/null +++ b/logging/rtc_event_log/fake_rtc_event_log_factory.cc @@ -0,0 +1,34 @@ +/* + * Copyright 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 "logging/rtc_event_log/fake_rtc_event_log_factory.h" + +#include + +#include "logging/rtc_event_log/rtc_event_log.h" + +namespace webrtc { + +std::unique_ptr FakeRtcEventLogFactory::CreateRtcEventLog( + RtcEventLog::EncodingType encoding_type) { + std::unique_ptr fake_event_log(new FakeRtcEventLog(thread())); + last_log_created_ = fake_event_log.get(); + return fake_event_log; +} + +std::unique_ptr FakeRtcEventLogFactory::CreateRtcEventLog( + RtcEventLog::EncodingType encoding_type, + std::unique_ptr task_queue) { + std::unique_ptr fake_event_log(new FakeRtcEventLog(thread())); + last_log_created_ = fake_event_log.get(); + return fake_event_log; +} + +} // namespace webrtc diff --git a/logging/rtc_event_log/fake_rtc_event_log_factory.h b/logging/rtc_event_log/fake_rtc_event_log_factory.h new file mode 100644 index 0000000000..1160e5464c --- /dev/null +++ b/logging/rtc_event_log/fake_rtc_event_log_factory.h @@ -0,0 +1,44 @@ +/* + * Copyright 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. + */ + +#ifndef LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_FACTORY_H_ +#define LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_FACTORY_H_ + +#include + +#include "logging/rtc_event_log/fake_rtc_event_log.h" +#include "logging/rtc_event_log/rtc_event_log_factory_interface.h" +#include "rtc_base/thread.h" + +namespace webrtc { + +class FakeRtcEventLogFactory : public RtcEventLogFactoryInterface { + public: + explicit FakeRtcEventLogFactory(rtc::Thread* thread) : thread_(thread) {} + ~FakeRtcEventLogFactory() override {} + + std::unique_ptr CreateRtcEventLog( + RtcEventLog::EncodingType encoding_type) override; + + std::unique_ptr CreateRtcEventLog( + RtcEventLog::EncodingType encoding_type, + std::unique_ptr task_queue) override; + + webrtc::RtcEventLog* last_log_created() { return last_log_created_; } + rtc::Thread* thread() { return thread_; } + + private: + webrtc::RtcEventLog* last_log_created_; + rtc::Thread* thread_; +}; + +} // namespace webrtc + +#endif // LOGGING_RTC_EVENT_LOG_FAKE_RTC_EVENT_LOG_FACTORY_H_ diff --git a/pc/BUILD.gn b/pc/BUILD.gn index e0b701da35..a7a7c56d58 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -74,6 +74,7 @@ rtc_static_library("rtc_pc_base") { "../call:rtp_interfaces", "../call:rtp_receiver", "../common_video:common_video", + "../logging:rtc_event_log_api", "../media:rtc_data", "../media:rtc_h264_profile_id", "../media:rtc_media_base", @@ -485,6 +486,7 @@ if (rtc_include_tests) { "../api:libjingle_peerconnection_api", "../api:mock_rtp", "../api/units:time_delta", + "../logging:fake_rtc_event_log", "../rtc_base:checks", "../rtc_base:stringutils", "../test:fileutils", diff --git a/pc/jseptransportcontroller.cc b/pc/jseptransportcontroller.cc index d05339e1a1..2d3eeb9b70 100644 --- a/pc/jseptransportcontroller.cc +++ b/pc/jseptransportcontroller.cc @@ -394,7 +394,7 @@ JsepTransportController::CreateDtlsTransport(const std::string& transport_name, std::move(ice), config_.crypto_options); } else { auto ice = rtc::MakeUnique( - transport_name, component, port_allocator_); + transport_name, component, port_allocator_, config_.event_log); dtls = rtc::MakeUnique(std::move(ice), config_.crypto_options); } diff --git a/pc/jseptransportcontroller.h b/pc/jseptransportcontroller.h index ebe105b510..dee05faee8 100644 --- a/pc/jseptransportcontroller.h +++ b/pc/jseptransportcontroller.h @@ -19,6 +19,7 @@ #include "api/candidate.h" #include "api/peerconnectioninterface.h" +#include "logging/rtc_event_log/rtc_event_log.h" #include "media/sctp/sctptransportinternal.h" #include "p2p/base/dtlstransport.h" #include "p2p/base/p2ptransportchannel.h" @@ -77,6 +78,7 @@ class JsepTransportController : public sigslot::has_slots<>, // Used to inject the ICE/DTLS transports created externally. cricket::TransportFactoryInterface* external_transport_factory = nullptr; Observer* transport_observer = nullptr; + RtcEventLog* event_log = nullptr; }; // The ICE related events are signaled on the |signaling_thread|. @@ -317,7 +319,7 @@ class JsepTransportController : public sigslot::has_slots<>, rtc::scoped_refptr certificate_; rtc::AsyncInvoker invoker_; - webrtc::MetricsObserverInterface* metrics_observer_ = nullptr; + MetricsObserverInterface* metrics_observer_ = nullptr; RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransportController); }; diff --git a/pc/peerconnection.cc b/pc/peerconnection.cc index 0a984a703f..093e72d77b 100644 --- a/pc/peerconnection.cc +++ b/pc/peerconnection.cc @@ -934,6 +934,7 @@ bool PeerConnection::Initialize( config.rtcp_mux_policy = configuration.rtcp_mux_policy; config.crypto_options = options.crypto_options; config.transport_observer = this; + config.event_log = event_log_.get(); #if defined(ENABLE_EXTERNAL_AUTH) config.enable_external_auth = true; #endif diff --git a/pc/peerconnection_integrationtest.cc b/pc/peerconnection_integrationtest.cc index ecd84d1422..186da00b96 100644 --- a/pc/peerconnection_integrationtest.cc +++ b/pc/peerconnection_integrationtest.cc @@ -33,7 +33,12 @@ #include "api/video_codecs/builtin_video_decoder_factory.h" #include "api/video_codecs/builtin_video_encoder_factory.h" #include "api/video_codecs/sdp_video_format.h" +#include "call/call.h" +#include "logging/rtc_event_log/fake_rtc_event_log_factory.h" +#include "logging/rtc_event_log/rtc_event_log_factory_interface.h" #include "media/engine/fakewebrtcvideoengine.h" +#include "media/engine/webrtcmediaengine.h" +#include "modules/audio_processing/include/audio_processing.h" #include "p2p/base/p2pconstants.h" #include "p2p/base/portinterface.h" #include "p2p/base/teststunserver.h" @@ -239,7 +244,7 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, webrtc::PeerConnectionDependencies dependencies(nullptr); dependencies.cert_generator = std::move(cert_generator); if (!client->Init(nullptr, nullptr, nullptr, std::move(dependencies), - network_thread, worker_thread)) { + network_thread, worker_thread, nullptr)) { delete client; return nullptr; } @@ -555,6 +560,10 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, } cricket::PortAllocator* port_allocator() const { return port_allocator_; } + webrtc::FakeRtcEventLogFactory* event_log_factory() const { + return event_log_factory_; + } + private: explicit PeerConnectionWrapper(const std::string& debug_name) : debug_name_(debug_name) {} @@ -564,7 +573,8 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, const PeerConnectionInterface::RTCConfiguration* config, webrtc::PeerConnectionDependencies dependencies, rtc::Thread* network_thread, - rtc::Thread* worker_thread) { + rtc::Thread* worker_thread, + std::unique_ptr event_log_factory) { // There's an error in this test code if Init ends up being called twice. RTC_DCHECK(!peer_connection_); RTC_DCHECK(!peer_connection_factory_); @@ -580,15 +590,31 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, return false; } rtc::Thread* const signaling_thread = rtc::Thread::Current(); - peer_connection_factory_ = webrtc::CreatePeerConnectionFactory( - network_thread, worker_thread, signaling_thread, - rtc::scoped_refptr( - fake_audio_capture_module_), - webrtc::CreateBuiltinAudioEncoderFactory(), - webrtc::CreateBuiltinAudioDecoderFactory(), - webrtc::CreateBuiltinVideoEncoderFactory(), - webrtc::CreateBuiltinVideoDecoderFactory(), nullptr /* audio_mixer */, - nullptr /* audio_processing */); + + webrtc::PeerConnectionFactoryDependencies pc_factory_dependencies; + pc_factory_dependencies.network_thread = network_thread; + pc_factory_dependencies.worker_thread = worker_thread; + pc_factory_dependencies.signaling_thread = signaling_thread; + pc_factory_dependencies.media_engine = + cricket::WebRtcMediaEngineFactory::Create( + rtc::scoped_refptr( + fake_audio_capture_module_), + webrtc::CreateBuiltinAudioEncoderFactory(), + webrtc::CreateBuiltinAudioDecoderFactory(), + webrtc::CreateBuiltinVideoEncoderFactory(), + webrtc::CreateBuiltinVideoDecoderFactory(), nullptr, + webrtc::AudioProcessingBuilder().Create()); + pc_factory_dependencies.call_factory = webrtc::CreateCallFactory(); + if (event_log_factory) { + event_log_factory_ = event_log_factory.get(); + pc_factory_dependencies.event_log_factory = std::move(event_log_factory); + } else { + pc_factory_dependencies.event_log_factory = + webrtc::CreateRtcEventLogFactory(); + } + peer_connection_factory_ = webrtc::CreateModularPeerConnectionFactory( + std::move(pc_factory_dependencies)); + if (!peer_connection_factory_) { return false; } @@ -952,6 +978,8 @@ class PeerConnectionWrapper : public webrtc::PeerConnectionObserver, std::vector ice_gathering_state_history_; + webrtc::FakeRtcEventLogFactory* event_log_factory_; + rtc::AsyncInvoker invoker_; friend class PeerConnectionIntegrationBaseTest; @@ -1114,12 +1142,15 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { webrtc::PeerConnectionInterface::kIceConnectionCompleted); } + // When |event_log_factory| is null, the default implementation of the event + // log factory will be used. std::unique_ptr CreatePeerConnectionWrapper( const std::string& debug_name, const MediaConstraintsInterface* constraints, const PeerConnectionFactory::Options* options, const RTCConfiguration* config, - webrtc::PeerConnectionDependencies dependencies) { + webrtc::PeerConnectionDependencies dependencies, + std::unique_ptr event_log_factory) { RTCConfiguration modified_config; if (config) { modified_config = *config; @@ -1134,12 +1165,26 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { if (!client->Init(constraints, options, &modified_config, std::move(dependencies), network_thread_.get(), - worker_thread_.get())) { + worker_thread_.get(), std::move(event_log_factory))) { return nullptr; } return client; } + std::unique_ptr + CreatePeerConnectionWrapperWithFakeRtcEventLog( + const std::string& debug_name, + const MediaConstraintsInterface* constraints, + const PeerConnectionFactory::Options* options, + const RTCConfiguration* config, + webrtc::PeerConnectionDependencies dependencies) { + std::unique_ptr event_log_factory( + new webrtc::FakeRtcEventLogFactory(rtc::Thread::Current())); + return CreatePeerConnectionWrapper(debug_name, constraints, options, config, + std::move(dependencies), + std::move(event_log_factory)); + } + bool CreatePeerConnectionWrappers() { return CreatePeerConnectionWrappersWithConfig( PeerConnectionInterface::RTCConfiguration(), @@ -1158,11 +1203,11 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { sdp_semantics_ = caller_semantics; caller_ = CreatePeerConnectionWrapper( "Caller", nullptr, nullptr, nullptr, - webrtc::PeerConnectionDependencies(nullptr)); + webrtc::PeerConnectionDependencies(nullptr), nullptr); sdp_semantics_ = callee_semantics; callee_ = CreatePeerConnectionWrapper( "Callee", nullptr, nullptr, nullptr, - webrtc::PeerConnectionDependencies(nullptr)); + webrtc::PeerConnectionDependencies(nullptr), nullptr); sdp_semantics_ = original_semantics; return caller_ && callee_; } @@ -1172,10 +1217,10 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { MediaConstraintsInterface* callee_constraints) { caller_ = CreatePeerConnectionWrapper( "Caller", caller_constraints, nullptr, nullptr, - webrtc::PeerConnectionDependencies(nullptr)); + webrtc::PeerConnectionDependencies(nullptr), nullptr); callee_ = CreatePeerConnectionWrapper( "Callee", callee_constraints, nullptr, nullptr, - webrtc::PeerConnectionDependencies(nullptr)); + webrtc::PeerConnectionDependencies(nullptr), nullptr); return caller_ && callee_; } @@ -1185,10 +1230,10 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { const PeerConnectionInterface::RTCConfiguration& callee_config) { caller_ = CreatePeerConnectionWrapper( "Caller", nullptr, nullptr, &caller_config, - webrtc::PeerConnectionDependencies(nullptr)); + webrtc::PeerConnectionDependencies(nullptr), nullptr); callee_ = CreatePeerConnectionWrapper( "Callee", nullptr, nullptr, &callee_config, - webrtc::PeerConnectionDependencies(nullptr)); + webrtc::PeerConnectionDependencies(nullptr), nullptr); return caller_ && callee_; } @@ -1199,10 +1244,10 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { webrtc::PeerConnectionDependencies callee_dependencies) { caller_ = CreatePeerConnectionWrapper("Caller", nullptr, nullptr, &caller_config, - std::move(caller_dependencies)); + std::move(caller_dependencies), nullptr); callee_ = CreatePeerConnectionWrapper("Callee", nullptr, nullptr, &callee_config, - std::move(callee_dependencies)); + std::move(callee_dependencies), nullptr); return caller_ && callee_; } @@ -1211,9 +1256,20 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { const PeerConnectionFactory::Options& callee_options) { caller_ = CreatePeerConnectionWrapper( "Caller", nullptr, &caller_options, nullptr, - webrtc::PeerConnectionDependencies(nullptr)); + webrtc::PeerConnectionDependencies(nullptr), nullptr); callee_ = CreatePeerConnectionWrapper( "Callee", nullptr, &callee_options, nullptr, + webrtc::PeerConnectionDependencies(nullptr), nullptr); + return caller_ && callee_; + } + + bool CreatePeerConnectionWrappersWithFakeRtcEventLog() { + PeerConnectionInterface::RTCConfiguration default_config; + caller_ = CreatePeerConnectionWrapperWithFakeRtcEventLog( + "Caller", nullptr, nullptr, &default_config, + webrtc::PeerConnectionDependencies(nullptr)); + callee_ = CreatePeerConnectionWrapperWithFakeRtcEventLog( + "Callee", nullptr, nullptr, &default_config, webrtc::PeerConnectionDependencies(nullptr)); return caller_ && callee_; } @@ -1227,7 +1283,7 @@ class PeerConnectionIntegrationBaseTest : public testing::Test { webrtc::PeerConnectionDependencies dependencies(nullptr); dependencies.cert_generator = std::move(cert_generator); return CreatePeerConnectionWrapper("New Peer", nullptr, nullptr, nullptr, - std::move(dependencies)); + std::move(dependencies), nullptr); } // Once called, SDP blobs and ICE candidates will be automatically signaled @@ -4354,6 +4410,39 @@ TEST_P(PeerConnectionIntegrationTest, } #endif // HAVE_SCTP +TEST_P(PeerConnectionIntegrationTest, + IceEventsGeneratedAndLoggedInRtcEventLog) { + ASSERT_TRUE(CreatePeerConnectionWrappersWithFakeRtcEventLog()); + ConnectFakeSignaling(); + PeerConnectionInterface::RTCOfferAnswerOptions options; + options.offer_to_receive_audio = 1; + caller()->SetOfferAnswerOptions(options); + caller()->CreateAndSetAndSignalOffer(); + ASSERT_TRUE_WAIT(DtlsConnected(), kDefaultTimeout); + ASSERT_NE(nullptr, caller()->event_log_factory()); + ASSERT_NE(nullptr, callee()->event_log_factory()); + webrtc::FakeRtcEventLog* caller_event_log = + static_cast( + caller()->event_log_factory()->last_log_created()); + webrtc::FakeRtcEventLog* callee_event_log = + static_cast( + callee()->event_log_factory()->last_log_created()); + ASSERT_NE(nullptr, caller_event_log); + ASSERT_NE(nullptr, callee_event_log); + int caller_ice_config_count = caller_event_log->GetEventCount( + webrtc::RtcEvent::Type::IceCandidatePairConfig); + int caller_ice_event_count = caller_event_log->GetEventCount( + webrtc::RtcEvent::Type::IceCandidatePairEvent); + int callee_ice_config_count = callee_event_log->GetEventCount( + webrtc::RtcEvent::Type::IceCandidatePairConfig); + int callee_ice_event_count = callee_event_log->GetEventCount( + webrtc::RtcEvent::Type::IceCandidatePairEvent); + EXPECT_LT(0, caller_ice_config_count); + EXPECT_LT(0, caller_ice_event_count); + EXPECT_LT(0, callee_ice_config_count); + EXPECT_LT(0, callee_ice_event_count); +} + INSTANTIATE_TEST_CASE_P(PeerConnectionIntegrationTest, PeerConnectionIntegrationTest, Values(SdpSemantics::kPlanB,