xref: /aosp_15_r20/external/webrtc/pc/peer_connection_wrapper.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1 /*
2  *  Copyright 2017 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 
11 #include "pc/peer_connection_wrapper.h"
12 
13 #include <stdint.h>
14 
15 #include <utility>
16 #include <vector>
17 
18 #include "api/function_view.h"
19 #include "api/set_remote_description_observer_interface.h"
20 #include "pc/sdp_utils.h"
21 #include "pc/test/fake_video_track_source.h"
22 #include "rtc_base/checks.h"
23 #include "rtc_base/gunit.h"
24 #include "rtc_base/logging.h"
25 #include "test/gtest.h"
26 
27 namespace webrtc {
28 
29 using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
30 
31 namespace {
32 const uint32_t kDefaultTimeout = 10000U;
33 }
34 
PeerConnectionWrapper(rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,rtc::scoped_refptr<PeerConnectionInterface> pc,std::unique_ptr<MockPeerConnectionObserver> observer)35 PeerConnectionWrapper::PeerConnectionWrapper(
36     rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
37     rtc::scoped_refptr<PeerConnectionInterface> pc,
38     std::unique_ptr<MockPeerConnectionObserver> observer)
39     : pc_factory_(std::move(pc_factory)),
40       observer_(std::move(observer)),
41       pc_(std::move(pc)) {
42   RTC_DCHECK(pc_factory_);
43   RTC_DCHECK(pc_);
44   RTC_DCHECK(observer_);
45   observer_->SetPeerConnectionInterface(pc_.get());
46 }
47 
~PeerConnectionWrapper()48 PeerConnectionWrapper::~PeerConnectionWrapper() {
49   if (pc_)
50     pc_->Close();
51 }
52 
pc_factory()53 PeerConnectionFactoryInterface* PeerConnectionWrapper::pc_factory() {
54   return pc_factory_.get();
55 }
56 
pc()57 PeerConnectionInterface* PeerConnectionWrapper::pc() {
58   return pc_.get();
59 }
60 
observer()61 MockPeerConnectionObserver* PeerConnectionWrapper::observer() {
62   return observer_.get();
63 }
64 
65 std::unique_ptr<SessionDescriptionInterface>
CreateOffer()66 PeerConnectionWrapper::CreateOffer() {
67   return CreateOffer(RTCOfferAnswerOptions());
68 }
69 
CreateOffer(const PeerConnectionInterface::RTCOfferAnswerOptions & options,std::string * error_out)70 std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateOffer(
71     const PeerConnectionInterface::RTCOfferAnswerOptions& options,
72     std::string* error_out) {
73   return CreateSdp(
74       [this, options](CreateSessionDescriptionObserver* observer) {
75         pc()->CreateOffer(observer, options);
76       },
77       error_out);
78 }
79 
80 std::unique_ptr<SessionDescriptionInterface>
CreateOfferAndSetAsLocal()81 PeerConnectionWrapper::CreateOfferAndSetAsLocal() {
82   return CreateOfferAndSetAsLocal(RTCOfferAnswerOptions());
83 }
84 
85 std::unique_ptr<SessionDescriptionInterface>
CreateOfferAndSetAsLocal(const PeerConnectionInterface::RTCOfferAnswerOptions & options)86 PeerConnectionWrapper::CreateOfferAndSetAsLocal(
87     const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
88   auto offer = CreateOffer(options);
89   if (!offer) {
90     return nullptr;
91   }
92   EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(offer.get())));
93   return offer;
94 }
95 
96 std::unique_ptr<SessionDescriptionInterface>
CreateAnswer()97 PeerConnectionWrapper::CreateAnswer() {
98   return CreateAnswer(RTCOfferAnswerOptions());
99 }
100 
101 std::unique_ptr<SessionDescriptionInterface>
CreateAnswer(const PeerConnectionInterface::RTCOfferAnswerOptions & options,std::string * error_out)102 PeerConnectionWrapper::CreateAnswer(
103     const PeerConnectionInterface::RTCOfferAnswerOptions& options,
104     std::string* error_out) {
105   return CreateSdp(
106       [this, options](CreateSessionDescriptionObserver* observer) {
107         pc()->CreateAnswer(observer, options);
108       },
109       error_out);
110 }
111 
112 std::unique_ptr<SessionDescriptionInterface>
CreateAnswerAndSetAsLocal()113 PeerConnectionWrapper::CreateAnswerAndSetAsLocal() {
114   return CreateAnswerAndSetAsLocal(RTCOfferAnswerOptions());
115 }
116 
117 std::unique_ptr<SessionDescriptionInterface>
CreateAnswerAndSetAsLocal(const PeerConnectionInterface::RTCOfferAnswerOptions & options)118 PeerConnectionWrapper::CreateAnswerAndSetAsLocal(
119     const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
120   auto answer = CreateAnswer(options);
121   if (!answer) {
122     return nullptr;
123   }
124   EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(answer.get())));
125   return answer;
126 }
127 
128 std::unique_ptr<SessionDescriptionInterface>
CreateRollback()129 PeerConnectionWrapper::CreateRollback() {
130   return CreateSessionDescription(SdpType::kRollback, "");
131 }
132 
CreateSdp(rtc::FunctionView<void (CreateSessionDescriptionObserver *)> fn,std::string * error_out)133 std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateSdp(
134     rtc::FunctionView<void(CreateSessionDescriptionObserver*)> fn,
135     std::string* error_out) {
136   auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
137   fn(observer.get());
138   EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
139   if (error_out && !observer->result()) {
140     *error_out = observer->error();
141   }
142   return observer->MoveDescription();
143 }
144 
SetLocalDescription(std::unique_ptr<SessionDescriptionInterface> desc,std::string * error_out)145 bool PeerConnectionWrapper::SetLocalDescription(
146     std::unique_ptr<SessionDescriptionInterface> desc,
147     std::string* error_out) {
148   return SetSdp(
149       [this, &desc](SetSessionDescriptionObserver* observer) {
150         pc()->SetLocalDescription(observer, desc.release());
151       },
152       error_out);
153 }
154 
SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,std::string * error_out)155 bool PeerConnectionWrapper::SetRemoteDescription(
156     std::unique_ptr<SessionDescriptionInterface> desc,
157     std::string* error_out) {
158   return SetSdp(
159       [this, &desc](SetSessionDescriptionObserver* observer) {
160         pc()->SetRemoteDescription(observer, desc.release());
161       },
162       error_out);
163 }
164 
SetRemoteDescription(std::unique_ptr<SessionDescriptionInterface> desc,RTCError * error_out)165 bool PeerConnectionWrapper::SetRemoteDescription(
166     std::unique_ptr<SessionDescriptionInterface> desc,
167     RTCError* error_out) {
168   auto observer = rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>();
169   pc()->SetRemoteDescription(std::move(desc), observer);
170   EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
171   bool ok = observer->error().ok();
172   if (error_out)
173     *error_out = std::move(observer->error());
174   return ok;
175 }
176 
SetSdp(rtc::FunctionView<void (SetSessionDescriptionObserver *)> fn,std::string * error_out)177 bool PeerConnectionWrapper::SetSdp(
178     rtc::FunctionView<void(SetSessionDescriptionObserver*)> fn,
179     std::string* error_out) {
180   auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
181   fn(observer.get());
182   EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
183   if (error_out && !observer->result()) {
184     *error_out = observer->error();
185   }
186   return observer->result();
187 }
188 
ExchangeOfferAnswerWith(PeerConnectionWrapper * answerer)189 bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
190     PeerConnectionWrapper* answerer) {
191   return ExchangeOfferAnswerWith(answerer, RTCOfferAnswerOptions(),
192                                  RTCOfferAnswerOptions());
193 }
194 
ExchangeOfferAnswerWith(PeerConnectionWrapper * answerer,const PeerConnectionInterface::RTCOfferAnswerOptions & offer_options,const PeerConnectionInterface::RTCOfferAnswerOptions & answer_options)195 bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
196     PeerConnectionWrapper* answerer,
197     const PeerConnectionInterface::RTCOfferAnswerOptions& offer_options,
198     const PeerConnectionInterface::RTCOfferAnswerOptions& answer_options) {
199   RTC_DCHECK(answerer);
200   if (answerer == this) {
201     RTC_LOG(LS_ERROR) << "Cannot exchange offer/answer with ourself!";
202     return false;
203   }
204   auto offer = CreateOffer(offer_options);
205   EXPECT_TRUE(offer);
206   if (!offer) {
207     return false;
208   }
209   bool set_local_offer =
210       SetLocalDescription(CloneSessionDescription(offer.get()));
211   EXPECT_TRUE(set_local_offer);
212   if (!set_local_offer) {
213     return false;
214   }
215   bool set_remote_offer = answerer->SetRemoteDescription(std::move(offer));
216   EXPECT_TRUE(set_remote_offer);
217   if (!set_remote_offer) {
218     return false;
219   }
220   auto answer = answerer->CreateAnswer(answer_options);
221   EXPECT_TRUE(answer);
222   if (!answer) {
223     return false;
224   }
225   bool set_local_answer =
226       answerer->SetLocalDescription(CloneSessionDescription(answer.get()));
227   EXPECT_TRUE(set_local_answer);
228   if (!set_local_answer) {
229     return false;
230   }
231   bool set_remote_answer = SetRemoteDescription(std::move(answer));
232   EXPECT_TRUE(set_remote_answer);
233   return set_remote_answer;
234 }
235 
236 rtc::scoped_refptr<RtpTransceiverInterface>
AddTransceiver(cricket::MediaType media_type)237 PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type) {
238   RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
239       pc()->AddTransceiver(media_type);
240   EXPECT_EQ(RTCErrorType::NONE, result.error().type());
241   return result.MoveValue();
242 }
243 
244 rtc::scoped_refptr<RtpTransceiverInterface>
AddTransceiver(cricket::MediaType media_type,const RtpTransceiverInit & init)245 PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type,
246                                       const RtpTransceiverInit& init) {
247   RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
248       pc()->AddTransceiver(media_type, init);
249   EXPECT_EQ(RTCErrorType::NONE, result.error().type());
250   return result.MoveValue();
251 }
252 
253 rtc::scoped_refptr<RtpTransceiverInterface>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track)254 PeerConnectionWrapper::AddTransceiver(
255     rtc::scoped_refptr<MediaStreamTrackInterface> track) {
256   RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
257       pc()->AddTransceiver(track);
258   EXPECT_EQ(RTCErrorType::NONE, result.error().type());
259   return result.MoveValue();
260 }
261 
262 rtc::scoped_refptr<RtpTransceiverInterface>
AddTransceiver(rtc::scoped_refptr<MediaStreamTrackInterface> track,const RtpTransceiverInit & init)263 PeerConnectionWrapper::AddTransceiver(
264     rtc::scoped_refptr<MediaStreamTrackInterface> track,
265     const RtpTransceiverInit& init) {
266   RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
267       pc()->AddTransceiver(track, init);
268   EXPECT_EQ(RTCErrorType::NONE, result.error().type());
269   return result.MoveValue();
270 }
271 
CreateAudioTrack(const std::string & label)272 rtc::scoped_refptr<AudioTrackInterface> PeerConnectionWrapper::CreateAudioTrack(
273     const std::string& label) {
274   return pc_factory()->CreateAudioTrack(label, nullptr);
275 }
276 
CreateVideoTrack(const std::string & label)277 rtc::scoped_refptr<VideoTrackInterface> PeerConnectionWrapper::CreateVideoTrack(
278     const std::string& label) {
279   return pc_factory()->CreateVideoTrack(label,
280                                         FakeVideoTrackSource::Create().get());
281 }
282 
AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string> & stream_ids)283 rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
284     rtc::scoped_refptr<MediaStreamTrackInterface> track,
285     const std::vector<std::string>& stream_ids) {
286   RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
287       pc()->AddTrack(track, stream_ids);
288   EXPECT_EQ(RTCErrorType::NONE, result.error().type());
289   return result.MoveValue();
290 }
291 
AddTrack(rtc::scoped_refptr<MediaStreamTrackInterface> track,const std::vector<std::string> & stream_ids,const std::vector<RtpEncodingParameters> & init_send_encodings)292 rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
293     rtc::scoped_refptr<MediaStreamTrackInterface> track,
294     const std::vector<std::string>& stream_ids,
295     const std::vector<RtpEncodingParameters>& init_send_encodings) {
296   RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
297       pc()->AddTrack(track, stream_ids, init_send_encodings);
298   EXPECT_EQ(RTCErrorType::NONE, result.error().type());
299   return result.MoveValue();
300 }
301 
AddAudioTrack(const std::string & track_label,const std::vector<std::string> & stream_ids)302 rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddAudioTrack(
303     const std::string& track_label,
304     const std::vector<std::string>& stream_ids) {
305   return AddTrack(CreateAudioTrack(track_label), stream_ids);
306 }
307 
AddVideoTrack(const std::string & track_label,const std::vector<std::string> & stream_ids)308 rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddVideoTrack(
309     const std::string& track_label,
310     const std::vector<std::string>& stream_ids) {
311   return AddTrack(CreateVideoTrack(track_label), stream_ids);
312 }
313 
314 rtc::scoped_refptr<DataChannelInterface>
CreateDataChannel(const std::string & label)315 PeerConnectionWrapper::CreateDataChannel(const std::string& label) {
316   auto result = pc()->CreateDataChannelOrError(label, nullptr);
317   if (!result.ok()) {
318     RTC_LOG(LS_ERROR) << "CreateDataChannel failed: "
319                       << ToString(result.error().type()) << " "
320                       << result.error().message();
321     return nullptr;
322   }
323   return result.MoveValue();
324 }
325 
326 PeerConnectionInterface::SignalingState
signaling_state()327 PeerConnectionWrapper::signaling_state() {
328   return pc()->signaling_state();
329 }
330 
IsIceGatheringDone()331 bool PeerConnectionWrapper::IsIceGatheringDone() {
332   return observer()->ice_gathering_complete_;
333 }
334 
IsIceConnected()335 bool PeerConnectionWrapper::IsIceConnected() {
336   return observer()->ice_connected_;
337 }
338 
339 rtc::scoped_refptr<const webrtc::RTCStatsReport>
GetStats()340 PeerConnectionWrapper::GetStats() {
341   auto callback = rtc::make_ref_counted<MockRTCStatsCollectorCallback>();
342   pc()->GetStats(callback.get());
343   EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
344   return callback->report();
345 }
346 
347 }  // namespace webrtc
348