|  | /* | 
|  | *  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_ |