blob: 653d8b7b0d69588e68580f29497198e6b3147359 [file] [log] [blame]
Steve Anton94286cb2017-09-26 16:20:19 -07001/*
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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/peer_connection_wrapper.h"
Steve Anton94286cb2017-09-26 16:20:19 -070012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
Steve Anton94286cb2017-09-26 16:20:19 -070015#include <utility>
Steve Anton36b29d12017-10-30 09:57:42 -070016#include <vector>
Steve Anton94286cb2017-09-26 16:20:19 -070017
Artem Titov741daaf2019-03-21 14:37:36 +010018#include "api/function_view.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "api/set_remote_description_observer_interface.h"
20#include "pc/sdp_utils.h"
21#include "pc/test/fake_video_track_source.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "rtc_base/checks.h"
Steve Anton94286cb2017-09-26 16:20:19 -070023#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010024#include "rtc_base/logging.h"
Yves Gerey3e707812018-11-28 16:47:49 +010025#include "test/gtest.h"
Steve Anton94286cb2017-09-26 16:20:19 -070026
27namespace webrtc {
28
Steve Anton22da89f2018-01-25 13:58:07 -080029using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
30
Steve Anton94286cb2017-09-26 16:20:19 -070031namespace {
Steve Anton6f25b092017-10-23 09:39:20 -070032const uint32_t kDefaultTimeout = 10000U;
Steve Anton94286cb2017-09-26 16:20:19 -070033}
34
35PeerConnectionWrapper::PeerConnectionWrapper(
36 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
37 rtc::scoped_refptr<PeerConnectionInterface> pc,
38 std::unique_ptr<MockPeerConnectionObserver> observer)
Mirko Bonadei2a823102017-11-13 11:50:33 +010039 : pc_factory_(std::move(pc_factory)),
40 observer_(std::move(observer)),
41 pc_(std::move(pc)) {
Steve Anton94286cb2017-09-26 16:20:19 -070042 RTC_DCHECK(pc_factory_);
43 RTC_DCHECK(pc_);
44 RTC_DCHECK(observer_);
45 observer_->SetPeerConnectionInterface(pc_.get());
46}
47
Tomas Gunnarsson2efb8a52021-04-01 16:26:57 +020048PeerConnectionWrapper::~PeerConnectionWrapper() {
49 if (pc_)
50 pc_->Close();
51}
Steve Anton94286cb2017-09-26 16:20:19 -070052
53PeerConnectionFactoryInterface* PeerConnectionWrapper::pc_factory() {
54 return pc_factory_.get();
55}
56
57PeerConnectionInterface* PeerConnectionWrapper::pc() {
58 return pc_.get();
59}
60
61MockPeerConnectionObserver* PeerConnectionWrapper::observer() {
62 return observer_.get();
63}
64
65std::unique_ptr<SessionDescriptionInterface>
66PeerConnectionWrapper::CreateOffer() {
Steve Anton22da89f2018-01-25 13:58:07 -080067 return CreateOffer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 16:20:19 -070068}
69
70std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateOffer(
Steve Anton8d3444d2017-10-20 15:30:51 -070071 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);
Steve Anton94286cb2017-09-26 16:20:19 -070078}
79
80std::unique_ptr<SessionDescriptionInterface>
81PeerConnectionWrapper::CreateOfferAndSetAsLocal() {
Steve Anton22da89f2018-01-25 13:58:07 -080082 return CreateOfferAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 15:30:51 -070083}
84
85std::unique_ptr<SessionDescriptionInterface>
86PeerConnectionWrapper::CreateOfferAndSetAsLocal(
87 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
88 auto offer = CreateOffer(options);
Steve Anton94286cb2017-09-26 16:20:19 -070089 if (!offer) {
90 return nullptr;
91 }
92 EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(offer.get())));
93 return offer;
94}
95
96std::unique_ptr<SessionDescriptionInterface>
97PeerConnectionWrapper::CreateAnswer() {
Steve Anton22da89f2018-01-25 13:58:07 -080098 return CreateAnswer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 16:20:19 -070099}
100
101std::unique_ptr<SessionDescriptionInterface>
102PeerConnectionWrapper::CreateAnswer(
Steve Anton8d3444d2017-10-20 15:30:51 -0700103 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);
Steve Anton94286cb2017-09-26 16:20:19 -0700110}
111
112std::unique_ptr<SessionDescriptionInterface>
113PeerConnectionWrapper::CreateAnswerAndSetAsLocal() {
Steve Anton22da89f2018-01-25 13:58:07 -0800114 return CreateAnswerAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 15:30:51 -0700115}
116
117std::unique_ptr<SessionDescriptionInterface>
118PeerConnectionWrapper::CreateAnswerAndSetAsLocal(
119 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
120 auto answer = CreateAnswer(options);
Steve Anton94286cb2017-09-26 16:20:19 -0700121 if (!answer) {
122 return nullptr;
123 }
124 EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(answer.get())));
125 return answer;
126}
127
Eldar Rello5ab79e62019-10-09 18:29:44 +0300128std::unique_ptr<SessionDescriptionInterface>
129PeerConnectionWrapper::CreateRollback() {
130 return CreateSessionDescription(SdpType::kRollback, "");
131}
132
Steve Anton94286cb2017-09-26 16:20:19 -0700133std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateSdp(
Mirko Bonadei2a823102017-11-13 11:50:33 +0100134 rtc::FunctionView<void(CreateSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 15:30:51 -0700135 std::string* error_out) {
Tommi87f70902021-04-27 14:43:08 +0200136 auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +0200137 fn(observer.get());
Steve Anton6f25b092017-10-23 09:39:20 -0700138 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700139 if (error_out && !observer->result()) {
140 *error_out = observer->error();
141 }
Steve Anton94286cb2017-09-26 16:20:19 -0700142 return observer->MoveDescription();
143}
144
145bool PeerConnectionWrapper::SetLocalDescription(
Steve Anton8d3444d2017-10-20 15:30:51 -0700146 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);
Steve Anton94286cb2017-09-26 16:20:19 -0700153}
154
155bool PeerConnectionWrapper::SetRemoteDescription(
Steve Anton8d3444d2017-10-20 15:30:51 -0700156 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);
Steve Anton94286cb2017-09-26 16:20:19 -0700163}
164
Henrik Boström31638672017-11-23 17:48:32 +0100165bool PeerConnectionWrapper::SetRemoteDescription(
166 std::unique_ptr<SessionDescriptionInterface> desc,
167 RTCError* error_out) {
Niels Möllere7cc8832022-01-04 15:20:03 +0100168 auto observer = rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>();
Henrik Boström31638672017-11-23 17:48:32 +0100169 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
Steve Anton94286cb2017-09-26 16:20:19 -0700177bool PeerConnectionWrapper::SetSdp(
Mirko Bonadei2a823102017-11-13 11:50:33 +0100178 rtc::FunctionView<void(SetSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 15:30:51 -0700179 std::string* error_out) {
Tommi87f70902021-04-27 14:43:08 +0200180 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 14:26:50 +0200181 fn(observer.get());
Steve Anton6f25b092017-10-23 09:39:20 -0700182 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700183 if (error_out && !observer->result()) {
184 *error_out = observer->error();
Steve Anton94286cb2017-09-26 16:20:19 -0700185 }
186 return observer->result();
187}
188
Steve Antondcc3c022017-12-22 16:02:54 -0800189bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
190 PeerConnectionWrapper* answerer) {
Steve Anton22da89f2018-01-25 13:58:07 -0800191 return ExchangeOfferAnswerWith(answerer, RTCOfferAnswerOptions(),
192 RTCOfferAnswerOptions());
193}
194
195bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
196 PeerConnectionWrapper* answerer,
197 const PeerConnectionInterface::RTCOfferAnswerOptions& offer_options,
198 const PeerConnectionInterface::RTCOfferAnswerOptions& answer_options) {
Steve Antondcc3c022017-12-22 16:02:54 -0800199 RTC_DCHECK(answerer);
200 if (answerer == this) {
201 RTC_LOG(LS_ERROR) << "Cannot exchange offer/answer with ourself!";
202 return false;
203 }
Steve Anton22da89f2018-01-25 13:58:07 -0800204 auto offer = CreateOffer(offer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800205 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 }
Steve Anton22da89f2018-01-25 13:58:07 -0800220 auto answer = answerer->CreateAnswer(answer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800221 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
Steve Anton9158ef62017-11-27 13:01:52 -0800236rtc::scoped_refptr<RtpTransceiverInterface>
237PeerConnectionWrapper::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
244rtc::scoped_refptr<RtpTransceiverInterface>
245PeerConnectionWrapper::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
253rtc::scoped_refptr<RtpTransceiverInterface>
254PeerConnectionWrapper::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
262rtc::scoped_refptr<RtpTransceiverInterface>
263PeerConnectionWrapper::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
272rtc::scoped_refptr<AudioTrackInterface> PeerConnectionWrapper::CreateAudioTrack(
273 const std::string& label) {
274 return pc_factory()->CreateAudioTrack(label, nullptr);
275}
276
277rtc::scoped_refptr<VideoTrackInterface> PeerConnectionWrapper::CreateVideoTrack(
278 const std::string& label) {
Niels Möllerafb246b2022-04-20 14:26:50 +0200279 return pc_factory()->CreateVideoTrack(label,
280 FakeVideoTrackSource::Create().get());
Steve Anton9158ef62017-11-27 13:01:52 -0800281}
282
Steve Anton2d6c76a2018-01-05 17:10:52 -0800283rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
284 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800285 const std::vector<std::string>& stream_ids) {
Steve Anton2d6c76a2018-01-05 17:10:52 -0800286 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
Seth Hampson845e8782018-03-02 11:34:10 -0800287 pc()->AddTrack(track, stream_ids);
Steve Anton2d6c76a2018-01-05 17:10:52 -0800288 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
289 return result.MoveValue();
290}
291
Jonas Oreland4b2a1062022-10-19 09:24:42 +0200292rtc::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
Steve Anton8d3444d2017-10-20 15:30:51 -0700302rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddAudioTrack(
303 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800304 const std::vector<std::string>& stream_ids) {
305 return AddTrack(CreateAudioTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700306}
307
Steve Anton8d3444d2017-10-20 15:30:51 -0700308rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddVideoTrack(
309 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800310 const std::vector<std::string>& stream_ids) {
311 return AddTrack(CreateVideoTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700312}
313
Steve Antonfa2260d2017-12-28 16:38:23 -0800314rtc::scoped_refptr<DataChannelInterface>
315PeerConnectionWrapper::CreateDataChannel(const std::string& label) {
Harald Alvestranda9af50f2021-05-21 13:33:51 +0000316 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();
Steve Antonfa2260d2017-12-28 16:38:23 -0800324}
325
Steve Anton8d3444d2017-10-20 15:30:51 -0700326PeerConnectionInterface::SignalingState
327PeerConnectionWrapper::signaling_state() {
328 return pc()->signaling_state();
Steve Anton94286cb2017-09-26 16:20:19 -0700329}
330
Steve Antonf1c6db12017-10-13 11:13:35 -0700331bool PeerConnectionWrapper::IsIceGatheringDone() {
Steve Anton6f25b092017-10-23 09:39:20 -0700332 return observer()->ice_gathering_complete_;
333}
334
335bool PeerConnectionWrapper::IsIceConnected() {
336 return observer()->ice_connected_;
337}
338
339rtc::scoped_refptr<const webrtc::RTCStatsReport>
340PeerConnectionWrapper::GetStats() {
Tommi87f70902021-04-27 14:43:08 +0200341 auto callback = rtc::make_ref_counted<MockRTCStatsCollectorCallback>();
Niels Möllerafb246b2022-04-20 14:26:50 +0200342 pc()->GetStats(callback.get());
Steve Anton6f25b092017-10-23 09:39:20 -0700343 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
344 return callback->report();
Steve Antonf1c6db12017-10-13 11:13:35 -0700345}
346
Steve Anton94286cb2017-09-26 16:20:19 -0700347} // namespace webrtc