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; ConfigConfig92 Config() { rtc_config.sdp_semantics = SdpSemantics::kUnifiedPlan; } 93 }; 94 95 struct VideoSendTrackConfig { 96 FrameGeneratorCapturerConfig generator; 97 bool screencast = false; 98 }; 99 100 struct AudioSendTrack { 101 rtc::scoped_refptr<AudioTrackInterface> track; 102 rtc::scoped_refptr<RtpSenderInterface> sender; 103 }; 104 105 struct VideoSendTrack { 106 FrameGeneratorCapturer* capturer; 107 FrameGeneratorCapturerVideoTrackSource* source; 108 VideoTrackInterface* track; 109 RtpSenderInterface* sender; 110 }; 111 112 PeerScenarioClient( 113 NetworkEmulationManager* net, 114 rtc::Thread* signaling_thread, 115 std::unique_ptr<LogWriterFactoryInterface> log_writer_factory, 116 Config config); 117 factory()118 PeerConnectionFactoryInterface* factory() { return pc_factory_.get(); } pc()119 PeerConnectionInterface* pc() { 120 RTC_DCHECK_RUN_ON(signaling_thread_); 121 return peer_connection_.get(); 122 } thread()123 rtc::Thread* thread() { return signaling_thread_; } clock()124 Clock* clock() { return Clock::GetRealTimeClock(); } 125 126 // Returns the endpoint created from the EmulatedEndpointConfig with the same 127 // index in PeerScenarioClient::config. 128 EmulatedEndpoint* endpoint(int index = 0); 129 130 AudioSendTrack CreateAudio(std::string track_id, 131 cricket::AudioOptions options); 132 VideoSendTrack CreateVideo(std::string track_id, VideoSendTrackConfig config); 133 134 void AddVideoReceiveSink(std::string track_id, 135 rtc::VideoSinkInterface<VideoFrame>* video_sink); 136 handlers()137 CallbackHandlers* handlers() { return &handlers_; } 138 139 // Note that there's no provision for munging SDP as that is deprecated 140 // behavior. 141 void CreateAndSetSdp(std::function<void(std::string)> offer_handler); 142 void SetSdpOfferAndGetAnswer(std::string remote_offer, 143 std::function<void(std::string)> answer_handler); 144 void SetSdpAnswer( 145 std::string remote_answer, 146 std::function<void(const SessionDescriptionInterface& answer)> 147 done_handler); 148 149 // Adds the given ice candidate when the peer connection is ready. 150 void AddIceCandidate(std::unique_ptr<IceCandidateInterface> candidate); 151 152 private: 153 const std::map<int, EmulatedEndpoint*> endpoints_; 154 TaskQueueFactory* const task_queue_factory_; 155 rtc::Thread* const signaling_thread_; 156 const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_; 157 const std::unique_ptr<rtc::Thread> worker_thread_; 158 CallbackHandlers handlers_ RTC_GUARDED_BY(signaling_thread_); 159 const std::unique_ptr<PeerConnectionObserver> observer_; 160 std::map<std::string, std::vector<rtc::VideoSinkInterface<VideoFrame>*>> 161 track_id_to_video_sinks_ RTC_GUARDED_BY(signaling_thread_); 162 std::list<std::unique_ptr<IceCandidateInterface>> pending_ice_candidates_ 163 RTC_GUARDED_BY(signaling_thread_); 164 165 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_; 166 rtc::scoped_refptr<PeerConnectionInterface> peer_connection_ 167 RTC_GUARDED_BY(signaling_thread_); 168 }; 169 170 } // namespace test 171 } // namespace webrtc 172 173 #endif // TEST_PEER_SCENARIO_PEER_SCENARIO_CLIENT_H_ 174