blob: 3b4d28f0d956e094a09477202343118200ce2548 [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) {
Henrik Boström831ae4e2020-07-29 12:04:00 +0200171 rtc::scoped_refptr<FakeSetRemoteDescriptionObserver> observer =
172 new FakeSetRemoteDescriptionObserver();
Henrik Boström31638672017-11-23 17:48:32 +0100173 pc()->SetRemoteDescription(std::move(desc), observer);
174 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
175 bool ok = observer->error().ok();
176 if (error_out)
177 *error_out = std::move(observer->error());
178 return ok;
179}
180
Steve Anton94286cb2017-09-26 16:20:19 -0700181bool PeerConnectionWrapper::SetSdp(
Mirko Bonadei2a823102017-11-13 11:50:33 +0100182 rtc::FunctionView<void(SetSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 15:30:51 -0700183 std::string* error_out) {
Tommi87f70902021-04-27 14:43:08 +0200184 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Steve Anton94286cb2017-09-26 16:20:19 -0700185 fn(observer);
Steve Anton6f25b092017-10-23 09:39:20 -0700186 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700187 if (error_out && !observer->result()) {
188 *error_out = observer->error();
Steve Anton94286cb2017-09-26 16:20:19 -0700189 }
190 return observer->result();
191}
192
Steve Antondcc3c022017-12-22 16:02:54 -0800193bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
194 PeerConnectionWrapper* answerer) {
Steve Anton22da89f2018-01-25 13:58:07 -0800195 return ExchangeOfferAnswerWith(answerer, RTCOfferAnswerOptions(),
196 RTCOfferAnswerOptions());
197}
198
199bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
200 PeerConnectionWrapper* answerer,
201 const PeerConnectionInterface::RTCOfferAnswerOptions& offer_options,
202 const PeerConnectionInterface::RTCOfferAnswerOptions& answer_options) {
Steve Antondcc3c022017-12-22 16:02:54 -0800203 RTC_DCHECK(answerer);
204 if (answerer == this) {
205 RTC_LOG(LS_ERROR) << "Cannot exchange offer/answer with ourself!";
206 return false;
207 }
Steve Anton22da89f2018-01-25 13:58:07 -0800208 auto offer = CreateOffer(offer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800209 EXPECT_TRUE(offer);
210 if (!offer) {
211 return false;
212 }
213 bool set_local_offer =
214 SetLocalDescription(CloneSessionDescription(offer.get()));
215 EXPECT_TRUE(set_local_offer);
216 if (!set_local_offer) {
217 return false;
218 }
219 bool set_remote_offer = answerer->SetRemoteDescription(std::move(offer));
220 EXPECT_TRUE(set_remote_offer);
221 if (!set_remote_offer) {
222 return false;
223 }
Steve Anton22da89f2018-01-25 13:58:07 -0800224 auto answer = answerer->CreateAnswer(answer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800225 EXPECT_TRUE(answer);
226 if (!answer) {
227 return false;
228 }
229 bool set_local_answer =
230 answerer->SetLocalDescription(CloneSessionDescription(answer.get()));
231 EXPECT_TRUE(set_local_answer);
232 if (!set_local_answer) {
233 return false;
234 }
235 bool set_remote_answer = SetRemoteDescription(std::move(answer));
236 EXPECT_TRUE(set_remote_answer);
237 return set_remote_answer;
238}
239
Steve Anton9158ef62017-11-27 13:01:52 -0800240rtc::scoped_refptr<RtpTransceiverInterface>
241PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type) {
242 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
243 pc()->AddTransceiver(media_type);
244 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
245 return result.MoveValue();
246}
247
248rtc::scoped_refptr<RtpTransceiverInterface>
249PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type,
250 const RtpTransceiverInit& init) {
251 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
252 pc()->AddTransceiver(media_type, init);
253 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
254 return result.MoveValue();
255}
256
257rtc::scoped_refptr<RtpTransceiverInterface>
258PeerConnectionWrapper::AddTransceiver(
259 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
260 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
261 pc()->AddTransceiver(track);
262 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
263 return result.MoveValue();
264}
265
266rtc::scoped_refptr<RtpTransceiverInterface>
267PeerConnectionWrapper::AddTransceiver(
268 rtc::scoped_refptr<MediaStreamTrackInterface> track,
269 const RtpTransceiverInit& init) {
270 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
271 pc()->AddTransceiver(track, init);
272 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
273 return result.MoveValue();
274}
275
276rtc::scoped_refptr<AudioTrackInterface> PeerConnectionWrapper::CreateAudioTrack(
277 const std::string& label) {
278 return pc_factory()->CreateAudioTrack(label, nullptr);
279}
280
281rtc::scoped_refptr<VideoTrackInterface> PeerConnectionWrapper::CreateVideoTrack(
282 const std::string& label) {
Niels Möllere8ae5df2018-05-29 09:13:57 +0200283 return pc_factory()->CreateVideoTrack(label, FakeVideoTrackSource::Create());
Steve Anton9158ef62017-11-27 13:01:52 -0800284}
285
Steve Anton2d6c76a2018-01-05 17:10:52 -0800286rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
287 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800288 const std::vector<std::string>& stream_ids) {
Steve Anton2d6c76a2018-01-05 17:10:52 -0800289 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
Seth Hampson845e8782018-03-02 11:34:10 -0800290 pc()->AddTrack(track, stream_ids);
Steve Anton2d6c76a2018-01-05 17:10:52 -0800291 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
292 return result.MoveValue();
293}
294
Steve Anton8d3444d2017-10-20 15:30:51 -0700295rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddAudioTrack(
296 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800297 const std::vector<std::string>& stream_ids) {
298 return AddTrack(CreateAudioTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700299}
300
Steve Anton8d3444d2017-10-20 15:30:51 -0700301rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddVideoTrack(
302 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800303 const std::vector<std::string>& stream_ids) {
304 return AddTrack(CreateVideoTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700305}
306
Steve Antonfa2260d2017-12-28 16:38:23 -0800307rtc::scoped_refptr<DataChannelInterface>
308PeerConnectionWrapper::CreateDataChannel(const std::string& label) {
Harald Alvestranda9af50f2021-05-21 13:33:51 +0000309 auto result = pc()->CreateDataChannelOrError(label, nullptr);
310 if (!result.ok()) {
311 RTC_LOG(LS_ERROR) << "CreateDataChannel failed: "
312 << ToString(result.error().type()) << " "
313 << result.error().message();
314 return nullptr;
315 }
316 return result.MoveValue();
Steve Antonfa2260d2017-12-28 16:38:23 -0800317}
318
Steve Anton8d3444d2017-10-20 15:30:51 -0700319PeerConnectionInterface::SignalingState
320PeerConnectionWrapper::signaling_state() {
321 return pc()->signaling_state();
Steve Anton94286cb2017-09-26 16:20:19 -0700322}
323
Steve Antonf1c6db12017-10-13 11:13:35 -0700324bool PeerConnectionWrapper::IsIceGatheringDone() {
Steve Anton6f25b092017-10-23 09:39:20 -0700325 return observer()->ice_gathering_complete_;
326}
327
328bool PeerConnectionWrapper::IsIceConnected() {
329 return observer()->ice_connected_;
330}
331
332rtc::scoped_refptr<const webrtc::RTCStatsReport>
333PeerConnectionWrapper::GetStats() {
Tommi87f70902021-04-27 14:43:08 +0200334 auto callback = rtc::make_ref_counted<MockRTCStatsCollectorCallback>();
Steve Anton6f25b092017-10-23 09:39:20 -0700335 pc()->GetStats(callback);
336 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
337 return callback->report();
Steve Antonf1c6db12017-10-13 11:13:35 -0700338}
339
Steve Anton94286cb2017-09-26 16:20:19 -0700340} // namespace webrtc