• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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