1 /* 2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 #ifndef TEST_PEER_SCENARIO_PEER_SCENARIO_CLIENT_H_ 11 #define TEST_PEER_SCENARIO_PEER_SCENARIO_CLIENT_H_ 12 13 #include <functional> 14 #include <list> 15 #include <map> 16 #include <memory> 17 #include <string> 18 #include <vector> 19 20 #include "absl/memory/memory.h" 21 #include "api/peer_connection_interface.h" 22 #include "api/test/network_emulation_manager.h" 23 #include "api/test/time_controller.h" 24 #include "pc/test/frame_generator_capturer_video_track_source.h" 25 #include "test/logging/log_writer.h" 26 27 namespace webrtc { 28 namespace test { 29 30 // Wrapper for a PeerConnection for use in PeerScenario tests. It's intended to 31 // be a minimal wrapper for a peer connection that's simple to use in testing. 32 // In particular the constructor hides a lot of the required setup for a peer 33 // connection. 34 class PeerScenarioClient { 35 public: 36 struct CallbackHandlers { 37 std::vector<std::function<void(PeerConnectionInterface::SignalingState)>> 38 on_signaling_change; 39 std::vector<std::function<void(rtc::scoped_refptr<DataChannelInterface>)>> 40 on_data_channel; 41 std::vector<std::function<void()>> on_renegotiation_needed; 42 std::vector< 43 std::function<void(PeerConnectionInterface::IceConnectionState)>> 44 on_standardized_ice_connection_change; 45 std::vector< 46 std::function<void(PeerConnectionInterface::PeerConnectionState)>> 47 on_connection_change; 48 std::vector<std::function<void(PeerConnectionInterface::IceGatheringState)>> 49 on_ice_gathering_change; 50 std::vector<std::function<void(const IceCandidateInterface*)>> 51 on_ice_candidate; 52 std::vector<std::function<void(const std::string&, 53 int, 54 const std::string&, 55 int, 56 const std::string&)>> 57 on_ice_candidate_error; 58 std::vector<std::function<void(const std::vector<cricket::Candidate>&)>> 59 on_ice_candidates_removed; 60 std::vector<std::function<void( 61 rtc::scoped_refptr<RtpReceiverInterface>, 62 const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&)>> 63 on_add_track; 64 std::vector< 65 std::function<void(rtc::scoped_refptr<RtpTransceiverInterface>)>> 66 on_track; 67 std::vector<std::function<void(rtc::scoped_refptr<RtpReceiverInterface>)>> 68 on_remove_track; 69 }; 70 struct Config { 71 // WebRTC only support one audio device that is setup up on construction, so 72 // we provide the audio generator configuration here rather than on creation 73 // of the tracks. This is unlike video, where multiple capture sources can 74 // be used at the same time. 75 struct AudioSource { 76 int sample_rate = 48000; 77 int channels = 1; 78 struct PulsedNoise { 79 double amplitude = 0.1; 80 }; 81 absl::optional<PulsedNoise> pulsed_noise = PulsedNoise(); 82 } audio; 83 struct Video { 84 bool use_fake_codecs = false; 85 } video; 86 // The created endpoints can be accessed using the map key as `index` in 87 // PeerScenarioClient::endpoint(index). 88 std::map<int, EmulatedEndpointConfig> endpoints = { 89 {0, EmulatedEndpointConfig()}}; 90 CallbackHandlers handlers; 91 PeerConnectionInterface::RTCConfiguration rtc_config; 92 bool disable_encryption = false; ConfigConfig93 Config() { rtc_config.sdp_semantics = SdpSemantics::kUnifiedPlan; } 94 }; 95 96 struct VideoSendTrackConfig { 97 FrameGeneratorCapturerConfig generator; 98 bool screencast = false; 99 }; 100 101 struct AudioSendTrack { 102 rtc::scoped_refptr<AudioTrackInterface> track; 103 rtc::scoped_refptr<RtpSenderInterface> sender; 104 }; 105 106 struct VideoSendTrack { 107 // Raw pointer to the capturer owned by `source`. 108 FrameGeneratorCapturer* capturer; 109 rtc::scoped_refptr<FrameGeneratorCapturerVideoTrackSource> source; 110 rtc::scoped_refptr<VideoTrackInterface> track; 111 rtc::scoped_refptr<RtpSenderInterface> sender; 112 }; 113 114 PeerScenarioClient( 115 NetworkEmulationManager* net, 116 rtc::Thread* signaling_thread, 117 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory, 118 Config config); 119 factory()120 PeerConnectionFactoryInterface* factory() { return pc_factory_.get(); } pc()121 PeerConnectionInterface* pc() { 122 RTC_DCHECK_RUN_ON(signaling_thread_); 123 return peer_connection_.get(); 124 } thread()125 rtc::Thread* thread() { return signaling_thread_; } clock()126 Clock* clock() { return Clock::GetRealTimeClock(); } 127 128 // Returns the endpoint created from the EmulatedEndpointConfig with the same 129 // index in PeerScenarioClient::config. 130 EmulatedEndpoint* endpoint(int index = 0); 131 132 AudioSendTrack CreateAudio(std::string track_id, 133 cricket::AudioOptions options); 134 VideoSendTrack CreateVideo(std::string track_id, VideoSendTrackConfig config); 135 136 void AddVideoReceiveSink(std::string track_id, 137 rtc::VideoSinkInterface<VideoFrame>* video_sink); 138 handlers()139 CallbackHandlers* handlers() { return &handlers_; } 140 141 // The `munge_offer` function can be used to munge the SDP, i.e. modify a 142 // local description afer creating it but before setting it. Note that this is 143 // legacy behavior. It's added here only to be able to have test coverage for 144 // scenarios even if they are not spec compliant. 145 void CreateAndSetSdp( 146 std::function<void(SessionDescriptionInterface*)> munge_offer, 147 std::function<void(std::string)> offer_handler); 148 void SetSdpOfferAndGetAnswer(std::string remote_offer, 149 std::function<void(std::string)> answer_handler); 150 void SetSdpAnswer( 151 std::string remote_answer, 152 std::function<void(const SessionDescriptionInterface& answer)> 153 done_handler); 154 155 // Adds the given ice candidate when the peer connection is ready. 156 void AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate); 157 158 private: 159 const std::map<int, EmulatedEndpoint*> endpoints_; 160 TaskQueueFactory* const task_queue_factory_; 161 rtc::Thread* const signaling_thread_; 162 const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_; 163 const std::unique_ptr<rtc::Thread> worker_thread_; 164 CallbackHandlers handlers_ RTC_GUARDED_BY(signaling_thread_); 165 const std::unique_ptr<PeerConnectionObserver> observer_; 166 std::map<std::string, std::vector<rtc::VideoSinkInterface<VideoFrame>*>> 167 track_id_to_video_sinks_ RTC_GUARDED_BY(signaling_thread_); 168 std::list<std::unique_ptr<IceCandidateInterface>> pending_ice_candidates_ 169 RTC_GUARDED_BY(signaling_thread_); 170 171 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_; 172 rtc::scoped_refptr<PeerConnectionInterface> peer_connection_ 173 RTC_GUARDED_BY(signaling_thread_); 174 }; 175 176 } // namespace test 177 } // namespace webrtc 178 179 #endif // TEST_PEER_SCENARIO_PEER_SCENARIO_CLIENT_H_ 180