blob: 65384ee447457ccb9ef0547ab2a57175132657ed [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) {
Steve Anton94286cb2017-09-26 16:20:19 -0700139 rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observer(
140 new rtc::RefCountedObject<MockCreateSessionDescriptionObserver>());
141 fn(observer);
Steve Anton6f25b092017-10-23 09:39:20 -0700142 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700143 if (error_out && !observer->result()) {
144 *error_out = observer->error();
145 }
Steve Anton94286cb2017-09-26 16:20:19 -0700146 return observer->MoveDescription();
147}
148
149bool PeerConnectionWrapper::SetLocalDescription(
Steve Anton8d3444d2017-10-20 15:30:51 -0700150 std::unique_ptr<SessionDescriptionInterface> desc,
151 std::string* error_out) {
152 return SetSdp(
153 [this, &desc](SetSessionDescriptionObserver* observer) {
154 pc()->SetLocalDescription(observer, desc.release());
155 },
156 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -0700157}
158
159bool PeerConnectionWrapper::SetRemoteDescription(
Steve Anton8d3444d2017-10-20 15:30:51 -0700160 std::unique_ptr<SessionDescriptionInterface> desc,
161 std::string* error_out) {
162 return SetSdp(
163 [this, &desc](SetSessionDescriptionObserver* observer) {
164 pc()->SetRemoteDescription(observer, desc.release());
165 },
166 error_out);
Steve Anton94286cb2017-09-26 16:20:19 -0700167}
168
Henrik Boström31638672017-11-23 17:48:32 +0100169bool PeerConnectionWrapper::SetRemoteDescription(
170 std::unique_ptr<SessionDescriptionInterface> desc,
171 RTCError* error_out) {
Henrik Boström831ae4e2020-07-29 12:04:00 +0200172 rtc::scoped_refptr<FakeSetRemoteDescriptionObserver> observer =
173 new FakeSetRemoteDescriptionObserver();
Henrik Boström31638672017-11-23 17:48:32 +0100174 pc()->SetRemoteDescription(std::move(desc), observer);
175 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
176 bool ok = observer->error().ok();
177 if (error_out)
178 *error_out = std::move(observer->error());
179 return ok;
180}
181
Steve Anton94286cb2017-09-26 16:20:19 -0700182bool PeerConnectionWrapper::SetSdp(
Mirko Bonadei2a823102017-11-13 11:50:33 +0100183 rtc::FunctionView<void(SetSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 15:30:51 -0700184 std::string* error_out) {
Steve Anton94286cb2017-09-26 16:20:19 -0700185 rtc::scoped_refptr<MockSetSessionDescriptionObserver> observer(
186 new rtc::RefCountedObject<MockSetSessionDescriptionObserver>());
187 fn(observer);
Steve Anton6f25b092017-10-23 09:39:20 -0700188 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 15:30:51 -0700189 if (error_out && !observer->result()) {
190 *error_out = observer->error();
Steve Anton94286cb2017-09-26 16:20:19 -0700191 }
192 return observer->result();
193}
194
Steve Antondcc3c022017-12-22 16:02:54 -0800195bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
196 PeerConnectionWrapper* answerer) {
Steve Anton22da89f2018-01-25 13:58:07 -0800197 return ExchangeOfferAnswerWith(answerer, RTCOfferAnswerOptions(),
198 RTCOfferAnswerOptions());
199}
200
201bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
202 PeerConnectionWrapper* answerer,
203 const PeerConnectionInterface::RTCOfferAnswerOptions& offer_options,
204 const PeerConnectionInterface::RTCOfferAnswerOptions& answer_options) {
Steve Antondcc3c022017-12-22 16:02:54 -0800205 RTC_DCHECK(answerer);
206 if (answerer == this) {
207 RTC_LOG(LS_ERROR) << "Cannot exchange offer/answer with ourself!";
208 return false;
209 }
Steve Anton22da89f2018-01-25 13:58:07 -0800210 auto offer = CreateOffer(offer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800211 EXPECT_TRUE(offer);
212 if (!offer) {
213 return false;
214 }
215 bool set_local_offer =
216 SetLocalDescription(CloneSessionDescription(offer.get()));
217 EXPECT_TRUE(set_local_offer);
218 if (!set_local_offer) {
219 return false;
220 }
221 bool set_remote_offer = answerer->SetRemoteDescription(std::move(offer));
222 EXPECT_TRUE(set_remote_offer);
223 if (!set_remote_offer) {
224 return false;
225 }
Steve Anton22da89f2018-01-25 13:58:07 -0800226 auto answer = answerer->CreateAnswer(answer_options);
Steve Antondcc3c022017-12-22 16:02:54 -0800227 EXPECT_TRUE(answer);
228 if (!answer) {
229 return false;
230 }
231 bool set_local_answer =
232 answerer->SetLocalDescription(CloneSessionDescription(answer.get()));
233 EXPECT_TRUE(set_local_answer);
234 if (!set_local_answer) {
235 return false;
236 }
237 bool set_remote_answer = SetRemoteDescription(std::move(answer));
238 EXPECT_TRUE(set_remote_answer);
239 return set_remote_answer;
240}
241
Steve Anton9158ef62017-11-27 13:01:52 -0800242rtc::scoped_refptr<RtpTransceiverInterface>
243PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type) {
244 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
245 pc()->AddTransceiver(media_type);
246 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
247 return result.MoveValue();
248}
249
250rtc::scoped_refptr<RtpTransceiverInterface>
251PeerConnectionWrapper::AddTransceiver(cricket::MediaType media_type,
252 const RtpTransceiverInit& init) {
253 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
254 pc()->AddTransceiver(media_type, init);
255 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
256 return result.MoveValue();
257}
258
259rtc::scoped_refptr<RtpTransceiverInterface>
260PeerConnectionWrapper::AddTransceiver(
261 rtc::scoped_refptr<MediaStreamTrackInterface> track) {
262 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
263 pc()->AddTransceiver(track);
264 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
265 return result.MoveValue();
266}
267
268rtc::scoped_refptr<RtpTransceiverInterface>
269PeerConnectionWrapper::AddTransceiver(
270 rtc::scoped_refptr<MediaStreamTrackInterface> track,
271 const RtpTransceiverInit& init) {
272 RTCErrorOr<rtc::scoped_refptr<RtpTransceiverInterface>> result =
273 pc()->AddTransceiver(track, init);
274 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
275 return result.MoveValue();
276}
277
278rtc::scoped_refptr<AudioTrackInterface> PeerConnectionWrapper::CreateAudioTrack(
279 const std::string& label) {
280 return pc_factory()->CreateAudioTrack(label, nullptr);
281}
282
283rtc::scoped_refptr<VideoTrackInterface> PeerConnectionWrapper::CreateVideoTrack(
284 const std::string& label) {
Niels Möllere8ae5df2018-05-29 09:13:57 +0200285 return pc_factory()->CreateVideoTrack(label, FakeVideoTrackSource::Create());
Steve Anton9158ef62017-11-27 13:01:52 -0800286}
287
Steve Anton2d6c76a2018-01-05 17:10:52 -0800288rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
289 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 11:34:10 -0800290 const std::vector<std::string>& stream_ids) {
Steve Anton2d6c76a2018-01-05 17:10:52 -0800291 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
Seth Hampson845e8782018-03-02 11:34:10 -0800292 pc()->AddTrack(track, stream_ids);
Steve Anton2d6c76a2018-01-05 17:10:52 -0800293 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
294 return result.MoveValue();
295}
296
Steve Anton8d3444d2017-10-20 15:30:51 -0700297rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddAudioTrack(
298 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800299 const std::vector<std::string>& stream_ids) {
300 return AddTrack(CreateAudioTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700301}
302
Steve Anton8d3444d2017-10-20 15:30:51 -0700303rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddVideoTrack(
304 const std::string& track_label,
Seth Hampson845e8782018-03-02 11:34:10 -0800305 const std::vector<std::string>& stream_ids) {
306 return AddTrack(CreateVideoTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 16:20:19 -0700307}
308
Steve Antonfa2260d2017-12-28 16:38:23 -0800309rtc::scoped_refptr<DataChannelInterface>
310PeerConnectionWrapper::CreateDataChannel(const std::string& label) {
311 return pc()->CreateDataChannel(label, nullptr);
312}
313
Steve Anton8d3444d2017-10-20 15:30:51 -0700314PeerConnectionInterface::SignalingState
315PeerConnectionWrapper::signaling_state() {
316 return pc()->signaling_state();
Steve Anton94286cb2017-09-26 16:20:19 -0700317}
318
Steve Antonf1c6db12017-10-13 11:13:35 -0700319bool PeerConnectionWrapper::IsIceGatheringDone() {
Steve Anton6f25b092017-10-23 09:39:20 -0700320 return observer()->ice_gathering_complete_;
321}
322
323bool PeerConnectionWrapper::IsIceConnected() {
324 return observer()->ice_connected_;
325}
326
327rtc::scoped_refptr<const webrtc::RTCStatsReport>
328PeerConnectionWrapper::GetStats() {
329 rtc::scoped_refptr<webrtc::MockRTCStatsCollectorCallback> callback(
330 new rtc::RefCountedObject<webrtc::MockRTCStatsCollectorCallback>());
331 pc()->GetStats(callback);
332 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
333 return callback->report();
Steve Antonf1c6db12017-10-13 11:13:35 -0700334}
335
Steve Anton94286cb2017-09-26 16:20:19 -0700336} // namespace webrtc