blob: 641d8bf053b935960bab0e1a4fd14f1a31fff12e [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 <memory>
16#include <string>
17#include <utility>
Steve Anton36b29d12017-10-30 09:57:42 -070018#include <vector>
Steve Anton94286cb2017-09-26 16:20:19 -070019
Artem Titov741daaf2019-03-21 14:37:36 +010020#include "api/function_view.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "api/set_remote_description_observer_interface.h"
22#include "pc/sdp_utils.h"
23#include "pc/test/fake_video_track_source.h"
Yves Gerey3e707812018-11-28 16:47:49 +010024#include "rtc_base/checks.h"
Steve Anton94286cb2017-09-26 16:20:19 -070025#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 16:47:49 +010026#include "rtc_base/logging.h"
Steve Anton10542f22019-01-11 09:11:00 -080027#include "rtc_base/ref_counted_object.h"
Yves Gerey3e707812018-11-28 16:47:49 +010028#include "test/gtest.h"
Steve Anton94286cb2017-09-26 16:20:19 -070029
30namespace webrtc {
31
Steve Anton22da89f2018-01-25 13:58:07 -080032using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
33
Steve Anton94286cb2017-09-26 16:20:19 -070034namespace {
Steve Anton6f25b092017-10-23 09:39:20 -070035const uint32_t kDefaultTimeout = 10000U;
Steve Anton94286cb2017-09-26 16:20:19 -070036}
37
38PeerConnectionWrapper::PeerConnectionWrapper(
39 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
40 rtc::scoped_refptr<PeerConnectionInterface> pc,
41 std::unique_ptr<MockPeerConnectionObserver> observer)
Mirko Bonadei2a823102017-11-13 11:50:33 +010042 : pc_factory_(std::move(pc_factory)),
43 observer_(std::move(observer)),
44 pc_(std::move(pc)) {
Steve Anton94286cb2017-09-26 16:20:19 -070045 RTC_DCHECK(pc_factory_);
46 RTC_DCHECK(pc_);
47 RTC_DCHECK(observer_);
48 observer_->SetPeerConnectionInterface(pc_.get());
49}
50
Tomas Gunnarsson2efb8a52021-04-01 16:26:57 +020051PeerConnectionWrapper::~PeerConnectionWrapper() {
52 if (pc_)
53 pc_->Close();
54}
Steve Anton94286cb2017-09-26 16:20:19 -070055
56PeerConnectionFactoryInterface* PeerConnectionWrapper::pc_factory() {
57 return pc_factory_.get();
58}
59
60PeerConnectionInterface* PeerConnectionWrapper::pc() {
61 return pc_.get();
62}
63
64MockPeerConnectionObserver* PeerConnectionWrapper::observer() {
65 return observer_.get();
66}
67
68std::unique_ptr<SessionDescriptionInterface>
69PeerConnectionWrapper::CreateOffer() {
Steve Anton22da89f2018-01-25 13:58:07 -080070 return CreateOffer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 16:20:19 -070071}
72
73std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateOffer(
Steve Anton8d3444d2017-10-20 15:30:51 -070074 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
75 std::string* error_out) {
76 return CreateSdp(
77 [this, options](CreateSessionDescriptionObserver* observer) {
78 pc()->CreateOffer(observer, options);
79 },
80 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -070081}
82
83std::unique_ptr<SessionDescriptionInterface>
84PeerConnectionWrapper::CreateOfferAndSetAsLocal() {
Steve Anton22da89f2018-01-25 13:58:07 -080085 return CreateOfferAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 15:30:51 -070086}
87
88std::unique_ptr<SessionDescriptionInterface>
89PeerConnectionWrapper::CreateOfferAndSetAsLocal(
90 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
91 auto offer = CreateOffer(options);
Steve Anton94286cb2017-09-26 16:20:19 -070092 if (!offer) {
93 return nullptr;
94 }
95 EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(offer.get())));
96 return offer;
97}
98
99std::unique_ptr<SessionDescriptionInterface>
100PeerConnectionWrapper::CreateAnswer() {
Steve Anton22da89f2018-01-25 13:58:07 -0800101 return CreateAnswer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 16:20:19 -0700102}
103
104std::unique_ptr<SessionDescriptionInterface>
105PeerConnectionWrapper::CreateAnswer(
Steve Anton8d3444d2017-10-20 15:30:51 -0700106 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
107 std::string* error_out) {
108 return CreateSdp(
109 [this, options](CreateSessionDescriptionObserver* observer) {
110 pc()->CreateAnswer(observer, options);
111 },
112 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -0700113}
114
115std::unique_ptr<SessionDescriptionInterface>
116PeerConnectionWrapper::CreateAnswerAndSetAsLocal() {
Steve Anton22da89f2018-01-25 13:58:07 -0800117 return CreateAnswerAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 15:30:51 -0700118}
119
120std::unique_ptr<SessionDescriptionInterface>
121PeerConnectionWrapper::CreateAnswerAndSetAsLocal(
122 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
123 auto answer = CreateAnswer(options);
Steve Anton94286cb2017-09-26 16:20:19 -0700124 if (!answer) {
125 return nullptr;
126 }
127 EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(answer.get())));
128 return answer;
129}
130
Eldar Rello5ab79e62019-10-09 18:29:44 +0300131std::unique_ptr<SessionDescriptionInterface>
132PeerConnectionWrapper::CreateRollback() {
133 return CreateSessionDescription(SdpType::kRollback, "");
134}
135
Steve Anton94286cb2017-09-26 16:20:19 -0700136std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateSdp(
Mirko Bonadei2a823102017-11-13 11:50:33 +0100137 rtc::FunctionView<void(CreateSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 15:30:51 -0700138 std::string* error_out) {
Tommi87f70902021-04-27 14:43:08 +0200139 auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
Steve Anton94286cb2017-09-26 16:20:19 -0700140 fn(observer);
Steve Anton6f25b092017-10-23 09:39:20 -0700141 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700142 if (error_out && !observer->result()) {
143 *error_out = observer->error();
144 }
Steve Anton94286cb2017-09-26 16:20:19 -0700145 return observer->MoveDescription();
146}
147
148bool PeerConnectionWrapper::SetLocalDescription(
Steve Anton8d3444d2017-10-20 15:30:51 -0700149 std::unique_ptr<SessionDescriptionInterface> desc,
150 std::string* error_out) {
151 return SetSdp(
152 [this, &desc](SetSessionDescriptionObserver* observer) {
153 pc()->SetLocalDescription(observer, desc.release());
154 },
155 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -0700156}
157
158bool PeerConnectionWrapper::SetRemoteDescription(
Steve Anton8d3444d2017-10-20 15:30:51 -0700159 std::unique_ptr<SessionDescriptionInterface> desc,
160 std::string* error_out) {
161 return SetSdp(
162 [this, &desc](SetSessionDescriptionObserver* observer) {
163 pc()->SetRemoteDescription(observer, desc.release());
164 },
165 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -0700166}
167
Henrik Boström31638672017-11-23 17:48:32 +0100168bool PeerConnectionWrapper::SetRemoteDescription(
169 std::unique_ptr<SessionDescriptionInterface> desc,
170 RTCError* error_out) {
Niels Möllere7cc8832022-01-04 15:20:03 +0100171 auto observer = rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>();
Henrik Boström31638672017-11-23 17:48:32 +0100172 pc()->SetRemoteDescription(std::move(desc), observer);
173 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
174 bool ok = observer->error().ok();
175 if (error_out)
176 *error_out = std::move(observer->error());
177 return ok;
178}
179
Steve Anton94286cb2017-09-26 16:20:19 -0700180bool PeerConnectionWrapper::SetSdp(
Mirko Bonadei2a823102017-11-13 11:50:33 +0100181 rtc::FunctionView<void(SetSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 15:30:51 -0700182 std::string* error_out) {
Tommi87f70902021-04-27 14:43:08 +0200183 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Steve Anton94286cb2017-09-26 16:20:19 -0700184 fn(observer);
Steve Anton6f25b092017-10-23 09:39:20 -0700185 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700186 if (error_out && !observer->result()) {
187 *error_out = observer->error();
Steve Anton94286cb2017-09-26 16:20:19 -0700188 }
189 return observer->result();
190}
191
Steve Antondcc3c022017-12-22 16:02:54 -0800192bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
193 PeerConnectionWrapper* answerer) {
Steve Anton22da89f2018-01-25 13:58:07 -0800194 return ExchangeOfferAnswerWith(answerer, RTCOfferAnswerOptions(),
195 RTCOfferAnswerOptions());
196}
197
198bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
199 PeerConnectionWrapper* answerer,
200 const PeerConnectionInterface::RTCOfferAnswerOptions& offer_options,
201 const PeerConnectionInterface::RTCOfferAnswerOptions& answer_options) {
Steve Antondcc3c022017-12-22 16:02:54 -0800202 RTC_DCHECK(answerer);
203 if (answerer == this) {
204 RTC_LOG(LS_ERROR) << "Cannot exchange offer/answer with ourself!";
205 return false;
206 }
Steve Anton22da89f2018-01-25 13:58:07 -0800207 auto offer = CreateOffer(offer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800208 EXPECT_TRUE(offer);
209 if (!offer) {
210 return false;
211 }
212 bool set_local_offer =
213 SetLocalDescription(CloneSessionDescription(offer.get()));
214 EXPECT_TRUE(set_local_offer);
215 if (!set_local_offer) {
216 return false;
217 }
218 bool set_remote_offer = answerer->SetRemoteDescription(std::move(offer));
219 EXPECT_TRUE(set_remote_offer);
220 if (!set_remote_offer) {
221 return false;
222 }
Steve Anton22da89f2018-01-25 13:58:07 -0800223 auto answer = answerer->CreateAnswer(answer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800224 EXPECT_TRUE(answer);
225 if (!answer) {
226 return false;
227 }
228 bool set_local_answer =
229 answerer->SetLocalDescription(CloneSessionDescription(answer.get()));
230 EXPECT_TRUE(set_local_answer);
231 if (!set_local_answer) {
232 return false;
233 }
234 bool set_remote_answer = SetRemoteDescription(std::move(answer));
235 EXPECT_TRUE(set_remote_answer);
236 return set_remote_answer;
237}
238
Steve Anton9158ef62017-11-27 13:01:52 -0800239rtc::scoped_refptr<RtpTransceiverInterface>
240PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type) {
241 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
242 pc()->AddTransceiver(media_type);
243 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
244 return result.MoveValue();
245}
246
247rtc::scoped_refptr<RtpTransceiverInterface>
248PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type,
249 const RtpTransceiverInit& init) {
250 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
251 pc()->AddTransceiver(media_type, init);
252 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
253 return result.MoveValue();
254}
255
256rtc::scoped_refptr<RtpTransceiverInterface>
257PeerConnectionWrapper::AddTransceiver(
258 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
259 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
260 pc()->AddTransceiver(track);
261 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
262 return result.MoveValue();
263}
264
265rtc::scoped_refptr<RtpTransceiverInterface>
266PeerConnectionWrapper::AddTransceiver(
267 rtc::scoped_refptr<MediaStreamTrackInterface> track,
268 const RtpTransceiverInit& init) {
269 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
270 pc()->AddTransceiver(track, init);
271 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
272 return result.MoveValue();
273}
274
275rtc::scoped_refptr<AudioTrackInterface> PeerConnectionWrapper::CreateAudioTrack(
276 const std::string& label) {
277 return pc_factory()->CreateAudioTrack(label, nullptr);
278}
279
280rtc::scoped_refptr<VideoTrackInterface> PeerConnectionWrapper::CreateVideoTrack(
281 const std::string& label) {
Niels Möllere8ae5df2018-05-29 09:13:57 +0200282 return pc_factory()->CreateVideoTrack(label, FakeVideoTrackSource::Create());
Steve Anton9158ef62017-11-27 13:01:52 -0800283}
284
Steve Anton2d6c76a2018-01-05 17:10:52 -0800285rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
286 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800287 const std::vector<std::string>& stream_ids) {
Steve Anton2d6c76a2018-01-05 17:10:52 -0800288 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
Seth Hampson845e8782018-03-02 11:34:10 -0800289 pc()->AddTrack(track, stream_ids);
Steve Anton2d6c76a2018-01-05 17:10:52 -0800290 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
291 return result.MoveValue();
292}
293
Steve Anton8d3444d2017-10-20 15:30:51 -0700294rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddAudioTrack(
295 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800296 const std::vector<std::string>& stream_ids) {
297 return AddTrack(CreateAudioTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700298}
299
Steve Anton8d3444d2017-10-20 15:30:51 -0700300rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddVideoTrack(
301 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800302 const std::vector<std::string>& stream_ids) {
303 return AddTrack(CreateVideoTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700304}
305
Steve Antonfa2260d2017-12-28 16:38:23 -0800306rtc::scoped_refptr<DataChannelInterface>
307PeerConnectionWrapper::CreateDataChannel(const std::string& label) {
Harald Alvestranda9af50f2021-05-21 13:33:51 +0000308 auto result = pc()->CreateDataChannelOrError(label, nullptr);
309 if (!result.ok()) {
310 RTC_LOG(LS_ERROR) << "CreateDataChannel failed: "
311 << ToString(result.error().type()) << " "
312 << result.error().message();
313 return nullptr;
314 }
315 return result.MoveValue();
Steve Antonfa2260d2017-12-28 16:38:23 -0800316}
317
Steve Anton8d3444d2017-10-20 15:30:51 -0700318PeerConnectionInterface::SignalingState
319PeerConnectionWrapper::signaling_state() {
320 return pc()->signaling_state();
Steve Anton94286cb2017-09-26 16:20:19 -0700321}
322
Steve Antonf1c6db12017-10-13 11:13:35 -0700323bool PeerConnectionWrapper::IsIceGatheringDone() {
Steve Anton6f25b092017-10-23 09:39:20 -0700324 return observer()->ice_gathering_complete_;
325}
326
327bool PeerConnectionWrapper::IsIceConnected() {
328 return observer()->ice_connected_;
329}
330
331rtc::scoped_refptr<const webrtc::RTCStatsReport>
332PeerConnectionWrapper::GetStats() {
Tommi87f70902021-04-27 14:43:08 +0200333 auto callback = rtc::make_ref_counted<MockRTCStatsCollectorCallback>();
Steve Anton6f25b092017-10-23 09:39:20 -0700334 pc()->GetStats(callback);
335 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
336 return callback->report();
Steve Antonf1c6db12017-10-13 11:13:35 -0700337}
338
Steve Anton94286cb2017-09-26 16:20:19 -0700339} // namespace webrtc