blob: 6a7a30edc0838b54ebda9774fb5325e15ec13fe1 [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"
Steve Anton10542f22019-01-11 09:11:00 -080025#include "rtc_base/ref_counted_object.h"
Yves Gerey3e707812018-11-28 16:47:49 +010026#include "test/gtest.h"
Steve Anton94286cb2017-09-26 16:20:19 -070027
28namespace webrtc {
29
Steve Anton22da89f2018-01-25 13:58:07 -080030using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
31
Steve Anton94286cb2017-09-26 16:20:19 -070032namespace {
Steve Anton6f25b092017-10-23 09:39:20 -070033const uint32_t kDefaultTimeout = 10000U;
Steve Anton94286cb2017-09-26 16:20:19 -070034}
35
36PeerConnectionWrapper::PeerConnectionWrapper(
37 rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
38 rtc::scoped_refptr<PeerConnectionInterface> pc,
39 std::unique_ptr<MockPeerConnectionObserver> observer)
Mirko Bonadei2a823102017-11-13 11:50:33 +010040 : pc_factory_(std::move(pc_factory)),
41 observer_(std::move(observer)),
42 pc_(std::move(pc)) {
Steve Anton94286cb2017-09-26 16:20:19 -070043 RTC_DCHECK(pc_factory_);
44 RTC_DCHECK(pc_);
45 RTC_DCHECK(observer_);
46 observer_->SetPeerConnectionInterface(pc_.get());
47}
48
Tomas Gunnarsson2efb8a52021-04-01 16:26:57 +020049PeerConnectionWrapper::~PeerConnectionWrapper() {
50 if (pc_)
51 pc_->Close();
52}
Steve Anton94286cb2017-09-26 16:20:19 -070053
54PeerConnectionFactoryInterface* PeerConnectionWrapper::pc_factory() {
55 return pc_factory_.get();
56}
57
58PeerConnectionInterface* PeerConnectionWrapper::pc() {
59 return pc_.get();
60}
61
62MockPeerConnectionObserver* PeerConnectionWrapper::observer() {
63 return observer_.get();
64}
65
66std::unique_ptr<SessionDescriptionInterface>
67PeerConnectionWrapper::CreateOffer() {
Steve Anton22da89f2018-01-25 13:58:07 -080068 return CreateOffer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 16:20:19 -070069}
70
71std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateOffer(
Steve Anton8d3444d2017-10-20 15:30:51 -070072 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
73 std::string* error_out) {
74 return CreateSdp(
75 [this, options](CreateSessionDescriptionObserver* observer) {
76 pc()->CreateOffer(observer, options);
77 },
78 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -070079}
80
81std::unique_ptr<SessionDescriptionInterface>
82PeerConnectionWrapper::CreateOfferAndSetAsLocal() {
Steve Anton22da89f2018-01-25 13:58:07 -080083 return CreateOfferAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 15:30:51 -070084}
85
86std::unique_ptr<SessionDescriptionInterface>
87PeerConnectionWrapper::CreateOfferAndSetAsLocal(
88 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
89 auto offer = CreateOffer(options);
Steve Anton94286cb2017-09-26 16:20:19 -070090 if (!offer) {
91 return nullptr;
92 }
93 EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(offer.get())));
94 return offer;
95}
96
97std::unique_ptr<SessionDescriptionInterface>
98PeerConnectionWrapper::CreateAnswer() {
Steve Anton22da89f2018-01-25 13:58:07 -080099 return CreateAnswer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 16:20:19 -0700100}
101
102std::unique_ptr<SessionDescriptionInterface>
103PeerConnectionWrapper::CreateAnswer(
Steve Anton8d3444d2017-10-20 15:30:51 -0700104 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
105 std::string* error_out) {
106 return CreateSdp(
107 [this, options](CreateSessionDescriptionObserver* observer) {
108 pc()->CreateAnswer(observer, options);
109 },
110 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -0700111}
112
113std::unique_ptr<SessionDescriptionInterface>
114PeerConnectionWrapper::CreateAnswerAndSetAsLocal() {
Steve Anton22da89f2018-01-25 13:58:07 -0800115 return CreateAnswerAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 15:30:51 -0700116}
117
118std::unique_ptr<SessionDescriptionInterface>
119PeerConnectionWrapper::CreateAnswerAndSetAsLocal(
120 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
121 auto answer = CreateAnswer(options);
Steve Anton94286cb2017-09-26 16:20:19 -0700122 if (!answer) {
123 return nullptr;
124 }
125 EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(answer.get())));
126 return answer;
127}
128
Eldar Rello5ab79e62019-10-09 18:29:44 +0300129std::unique_ptr<SessionDescriptionInterface>
130PeerConnectionWrapper::CreateRollback() {
131 return CreateSessionDescription(SdpType::kRollback, "");
132}
133
Steve Anton94286cb2017-09-26 16:20:19 -0700134std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateSdp(
Mirko Bonadei2a823102017-11-13 11:50:33 +0100135 rtc::FunctionView<void(CreateSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 15:30:51 -0700136 std::string* error_out) {
Tommi87f70902021-04-27 14:43:08 +0200137 auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
Steve Anton94286cb2017-09-26 16:20:19 -0700138 fn(observer);
Steve Anton6f25b092017-10-23 09:39:20 -0700139 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700140 if (error_out && !observer->result()) {
141 *error_out = observer->error();
142 }
Steve Anton94286cb2017-09-26 16:20:19 -0700143 return observer->MoveDescription();
144}
145
146bool PeerConnectionWrapper::SetLocalDescription(
Steve Anton8d3444d2017-10-20 15:30:51 -0700147 std::unique_ptr<SessionDescriptionInterface> desc,
148 std::string* error_out) {
149 return SetSdp(
150 [this, &desc](SetSessionDescriptionObserver* observer) {
151 pc()->SetLocalDescription(observer, desc.release());
152 },
153 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -0700154}
155
156bool PeerConnectionWrapper::SetRemoteDescription(
Steve Anton8d3444d2017-10-20 15:30:51 -0700157 std::unique_ptr<SessionDescriptionInterface> desc,
158 std::string* error_out) {
159 return SetSdp(
160 [this, &desc](SetSessionDescriptionObserver* observer) {
161 pc()->SetRemoteDescription(observer, desc.release());
162 },
163 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -0700164}
165
Henrik Boström31638672017-11-23 17:48:32 +0100166bool PeerConnectionWrapper::SetRemoteDescription(
167 std::unique_ptr<SessionDescriptionInterface> desc,
168 RTCError* error_out) {
Niels Möllere7cc8832022-01-04 15:20:03 +0100169 auto observer = rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>();
Henrik Boström31638672017-11-23 17:48:32 +0100170 pc()->SetRemoteDescription(std::move(desc), observer);
171 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
172 bool ok = observer->error().ok();
173 if (error_out)
174 *error_out = std::move(observer->error());
175 return ok;
176}
177
Steve Anton94286cb2017-09-26 16:20:19 -0700178bool PeerConnectionWrapper::SetSdp(
Mirko Bonadei2a823102017-11-13 11:50:33 +0100179 rtc::FunctionView<void(SetSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 15:30:51 -0700180 std::string* error_out) {
Tommi87f70902021-04-27 14:43:08 +0200181 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Steve Anton94286cb2017-09-26 16:20:19 -0700182 fn(observer);
Steve Anton6f25b092017-10-23 09:39:20 -0700183 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700184 if (error_out && !observer->result()) {
185 *error_out = observer->error();
Steve Anton94286cb2017-09-26 16:20:19 -0700186 }
187 return observer->result();
188}
189
Steve Antondcc3c022017-12-22 16:02:54 -0800190bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
191 PeerConnectionWrapper* answerer) {
Steve Anton22da89f2018-01-25 13:58:07 -0800192 return ExchangeOfferAnswerWith(answerer, RTCOfferAnswerOptions(),
193 RTCOfferAnswerOptions());
194}
195
196bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
197 PeerConnectionWrapper* answerer,
198 const PeerConnectionInterface::RTCOfferAnswerOptions& offer_options,
199 const PeerConnectionInterface::RTCOfferAnswerOptions& answer_options) {
Steve Antondcc3c022017-12-22 16:02:54 -0800200 RTC_DCHECK(answerer);
201 if (answerer == this) {
202 RTC_LOG(LS_ERROR) << "Cannot exchange offer/answer with ourself!";
203 return false;
204 }
Steve Anton22da89f2018-01-25 13:58:07 -0800205 auto offer = CreateOffer(offer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800206 EXPECT_TRUE(offer);
207 if (!offer) {
208 return false;
209 }
210 bool set_local_offer =
211 SetLocalDescription(CloneSessionDescription(offer.get()));
212 EXPECT_TRUE(set_local_offer);
213 if (!set_local_offer) {
214 return false;
215 }
216 bool set_remote_offer = answerer->SetRemoteDescription(std::move(offer));
217 EXPECT_TRUE(set_remote_offer);
218 if (!set_remote_offer) {
219 return false;
220 }
Steve Anton22da89f2018-01-25 13:58:07 -0800221 auto answer = answerer->CreateAnswer(answer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800222 EXPECT_TRUE(answer);
223 if (!answer) {
224 return false;
225 }
226 bool set_local_answer =
227 answerer->SetLocalDescription(CloneSessionDescription(answer.get()));
228 EXPECT_TRUE(set_local_answer);
229 if (!set_local_answer) {
230 return false;
231 }
232 bool set_remote_answer = SetRemoteDescription(std::move(answer));
233 EXPECT_TRUE(set_remote_answer);
234 return set_remote_answer;
235}
236
Steve Anton9158ef62017-11-27 13:01:52 -0800237rtc::scoped_refptr<RtpTransceiverInterface>
238PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type) {
239 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
240 pc()->AddTransceiver(media_type);
241 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
242 return result.MoveValue();
243}
244
245rtc::scoped_refptr<RtpTransceiverInterface>
246PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type,
247 const RtpTransceiverInit& init) {
248 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
249 pc()->AddTransceiver(media_type, init);
250 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
251 return result.MoveValue();
252}
253
254rtc::scoped_refptr<RtpTransceiverInterface>
255PeerConnectionWrapper::AddTransceiver(
256 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
257 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
258 pc()->AddTransceiver(track);
259 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
260 return result.MoveValue();
261}
262
263rtc::scoped_refptr<RtpTransceiverInterface>
264PeerConnectionWrapper::AddTransceiver(
265 rtc::scoped_refptr<MediaStreamTrackInterface> track,
266 const RtpTransceiverInit& init) {
267 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
268 pc()->AddTransceiver(track, init);
269 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
270 return result.MoveValue();
271}
272
273rtc::scoped_refptr<AudioTrackInterface> PeerConnectionWrapper::CreateAudioTrack(
274 const std::string& label) {
275 return pc_factory()->CreateAudioTrack(label, nullptr);
276}
277
278rtc::scoped_refptr<VideoTrackInterface> PeerConnectionWrapper::CreateVideoTrack(
279 const std::string& label) {
Niels Möllere8ae5df2018-05-29 09:13:57 +0200280 return pc_factory()->CreateVideoTrack(label, FakeVideoTrackSource::Create());
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
Steve Anton8d3444d2017-10-20 15:30:51 -0700292rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddAudioTrack(
293 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800294 const std::vector<std::string>& stream_ids) {
295 return AddTrack(CreateAudioTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700296}
297
Steve Anton8d3444d2017-10-20 15:30:51 -0700298rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddVideoTrack(
299 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800300 const std::vector<std::string>& stream_ids) {
301 return AddTrack(CreateVideoTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700302}
303
Steve Antonfa2260d2017-12-28 16:38:23 -0800304rtc::scoped_refptr<DataChannelInterface>
305PeerConnectionWrapper::CreateDataChannel(const std::string& label) {
Harald Alvestranda9af50f2021-05-21 13:33:51 +0000306 auto result = pc()->CreateDataChannelOrError(label, nullptr);
307 if (!result.ok()) {
308 RTC_LOG(LS_ERROR) << "CreateDataChannel failed: "
309 << ToString(result.error().type()) << " "
310 << result.error().message();
311 return nullptr;
312 }
313 return result.MoveValue();
Steve Antonfa2260d2017-12-28 16:38:23 -0800314}
315
Steve Anton8d3444d2017-10-20 15:30:51 -0700316PeerConnectionInterface::SignalingState
317PeerConnectionWrapper::signaling_state() {
318 return pc()->signaling_state();
Steve Anton94286cb2017-09-26 16:20:19 -0700319}
320
Steve Antonf1c6db12017-10-13 11:13:35 -0700321bool PeerConnectionWrapper::IsIceGatheringDone() {
Steve Anton6f25b092017-10-23 09:39:20 -0700322 return observer()->ice_gathering_complete_;
323}
324
325bool PeerConnectionWrapper::IsIceConnected() {
326 return observer()->ice_connected_;
327}
328
329rtc::scoped_refptr<const webrtc::RTCStatsReport>
330PeerConnectionWrapper::GetStats() {
Tommi87f70902021-04-27 14:43:08 +0200331 auto callback = rtc::make_ref_counted<MockRTCStatsCollectorCallback>();
Steve Anton6f25b092017-10-23 09:39:20 -0700332 pc()->GetStats(callback);
333 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
334 return callback->report();
Steve Antonf1c6db12017-10-13 11:13:35 -0700335}
336
Steve Anton94286cb2017-09-26 16:20:19 -0700337} // namespace webrtc