| /* |
| * 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. |
| */ |
| #ifndef TEST_PEER_SCENARIO_PEER_SCENARIO_CLIENT_H_ |
| #define TEST_PEER_SCENARIO_PEER_SCENARIO_CLIENT_H_ |
| |
| #include <functional> |
| #include <list> |
| #include <map> |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "absl/memory/memory.h" |
| #include "api/peer_connection_interface.h" |
| #include "api/test/network_emulation_manager.h" |
| #include "api/test/time_controller.h" |
| #include "pc/test/frame_generator_capturer_video_track_source.h" |
| #include "test/logging/log_writer.h" |
| |
| namespace webrtc { |
| namespace test { |
| |
| // Wrapper for a PeerConnection for use in PeerScenario tests. It's intended to |
| // be a minimal wrapper for a peer connection that's simple to use in testing. |
| // In particular the constructor hides a lot of the required setup for a peer |
| // connection. |
| class PeerScenarioClient { |
| public: |
| struct CallbackHandlers { |
| std::vector<std::function<void(PeerConnectionInterface::SignalingState)>> |
| on_signaling_change; |
| std::vector<std::function<void(rtc::scoped_refptr<DataChannelInterface>)>> |
| on_data_channel; |
| std::vector<std::function<void()>> on_renegotiation_needed; |
| std::vector< |
| std::function<void(PeerConnectionInterface::IceConnectionState)>> |
| on_standardized_ice_connection_change; |
| std::vector< |
| std::function<void(PeerConnectionInterface::PeerConnectionState)>> |
| on_connection_change; |
| std::vector<std::function<void(PeerConnectionInterface::IceGatheringState)>> |
| on_ice_gathering_change; |
| std::vector<std::function<void(const IceCandidateInterface*)>> |
| on_ice_candidate; |
| std::vector<std::function<void(const std::string&, |
| int, |
| const std::string&, |
| int, |
| const std::string&)>> |
| on_ice_candidate_error; |
| std::vector<std::function<void(const std::vector<cricket::Candidate>&)>> |
| on_ice_candidates_removed; |
| std::vector<std::function<void( |
| rtc::scoped_refptr<RtpReceiverInterface>, |
| const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&)>> |
| on_add_track; |
| std::vector< |
| std::function<void(rtc::scoped_refptr<RtpTransceiverInterface>)>> |
| on_track; |
| std::vector<std::function<void(rtc::scoped_refptr<RtpReceiverInterface>)>> |
| on_remove_track; |
| }; |
| struct Config { |
| // WebRTC only support one audio device that is setup up on construction, so |
| // we provide the audio generator configuration here rather than on creation |
| // of the tracks. This is unlike video, where multiple capture sources can |
| // be used at the same time. |
| struct AudioSource { |
| int sample_rate = 48000; |
| int channels = 1; |
| struct PulsedNoise { |
| double amplitude = 0.1; |
| }; |
| absl::optional<PulsedNoise> pulsed_noise = PulsedNoise(); |
| } audio; |
| struct Video { |
| bool use_fake_codecs = false; |
| } video; |
| // The created endpoints can be accessed using the map key as `index` in |
| // PeerScenarioClient::endpoint(index). |
| std::map<int, EmulatedEndpointConfig> endpoints = { |
| {0, EmulatedEndpointConfig()}}; |
| CallbackHandlers handlers; |
| PeerConnectionInterface::RTCConfiguration rtc_config; |
| bool disable_encryption = false; |
| Config() { rtc_config.sdp_semantics = SdpSemantics::kUnifiedPlan; } |
| }; |
| |
| struct VideoSendTrackConfig { |
| FrameGeneratorCapturerConfig generator; |
| bool screencast = false; |
| }; |
| |
| struct AudioSendTrack { |
| rtc::scoped_refptr<AudioTrackInterface> track; |
| rtc::scoped_refptr<RtpSenderInterface> sender; |
| }; |
| |
| struct VideoSendTrack { |
| FrameGeneratorCapturer* capturer; |
| FrameGeneratorCapturerVideoTrackSource* source; |
| VideoTrackInterface* track; |
| RtpSenderInterface* sender; |
| }; |
| |
| PeerScenarioClient( |
| NetworkEmulationManager* net, |
| rtc::Thread* signaling_thread, |
| std::unique_ptr<LogWriterFactoryInterface> log_writer_factory, |
| Config config); |
| |
| PeerConnectionFactoryInterface* factory() { return pc_factory_.get(); } |
| PeerConnectionInterface* pc() { |
| RTC_DCHECK_RUN_ON(signaling_thread_); |
| return peer_connection_.get(); |
| } |
| rtc::Thread* thread() { return signaling_thread_; } |
| Clock* clock() { return Clock::GetRealTimeClock(); } |
| |
| // Returns the endpoint created from the EmulatedEndpointConfig with the same |
| // index in PeerScenarioClient::config. |
| EmulatedEndpoint* endpoint(int index = 0); |
| |
| AudioSendTrack CreateAudio(std::string track_id, |
| cricket::AudioOptions options); |
| VideoSendTrack CreateVideo(std::string track_id, VideoSendTrackConfig config); |
| |
| void AddVideoReceiveSink(std::string track_id, |
| rtc::VideoSinkInterface<VideoFrame>* video_sink); |
| |
| CallbackHandlers* handlers() { return &handlers_; } |
| |
| // The `munge_offer` function can be used to munge the SDP, i.e. modify a |
| // local description afer creating it but before setting it. Note that this is |
| // legacy behavior. It's added here only to be able to have test coverage for |
| // scenarios even if they are not spec compliant. |
| void CreateAndSetSdp( |
| std::function<void(SessionDescriptionInterface*)> munge_offer, |
| std::function<void(std::string)> offer_handler); |
| void SetSdpOfferAndGetAnswer(std::string remote_offer, |
| std::function<void(std::string)> answer_handler); |
| void SetSdpAnswer( |
| std::string remote_answer, |
| std::function<void(const SessionDescriptionInterface& answer)> |
| done_handler); |
| |
| // Adds the given ice candidate when the peer connection is ready. |
| void AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate); |
| |
| private: |
| const std::map<int, EmulatedEndpoint*> endpoints_; |
| TaskQueueFactory* const task_queue_factory_; |
| rtc::Thread* const signaling_thread_; |
| const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_; |
| const std::unique_ptr<rtc::Thread> worker_thread_; |
| CallbackHandlers handlers_ RTC_GUARDED_BY(signaling_thread_); |
| const std::unique_ptr<PeerConnectionObserver> observer_; |
| std::map<std::string, std::vector<rtc::VideoSinkInterface<VideoFrame>*>> |
| track_id_to_video_sinks_ RTC_GUARDED_BY(signaling_thread_); |
| std::list<std::unique_ptr<IceCandidateInterface>> pending_ice_candidates_ |
| RTC_GUARDED_BY(signaling_thread_); |
| |
| rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_; |
| rtc::scoped_refptr<PeerConnectionInterface> peer_connection_ |
| RTC_GUARDED_BY(signaling_thread_); |
| }; |
| |
| } // namespace test |
| } // namespace webrtc |
| |
| #endif // TEST_PEER_SCENARIO_PEER_SCENARIO_CLIENT_H_ |