blob: 557d0c8422f514a1fd047790fd1916b048e1f2f6 [file] [log] [blame]
Steve Anton94286cb2017-09-26 23:20:191/*
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 17:11:0011#include "pc/peer_connection_wrapper.h"
Steve Anton94286cb2017-09-26 23:20:1912
Yves Gerey3e707812018-11-28 15:47:4913#include <stdint.h>
Jonas Olssona4d87372019-07-05 17:08:3314
Steve Anton94286cb2017-09-26 23:20:1915#include <utility>
Steve Anton36b29d12017-10-30 16:57:4216#include <vector>
Steve Anton94286cb2017-09-26 23:20:1917
Jeremy Leconteeccd93e2023-02-10 08:26:5018#include "absl/types/optional.h"
Artem Titov741daaf2019-03-21 13:37:3619#include "api/function_view.h"
Steve Anton10542f22019-01-11 17:11:0020#include "api/set_remote_description_observer_interface.h"
21#include "pc/sdp_utils.h"
22#include "pc/test/fake_video_track_source.h"
Yves Gerey3e707812018-11-28 15:47:4923#include "rtc_base/checks.h"
Steve Anton94286cb2017-09-26 23:20:1924#include "rtc_base/gunit.h"
Yves Gerey3e707812018-11-28 15:47:4925#include "rtc_base/logging.h"
Yves Gerey3e707812018-11-28 15:47:4926#include "test/gtest.h"
Steve Anton94286cb2017-09-26 23:20:1927
28namespace webrtc {
29
Steve Anton22da89f2018-01-25 21:58:0730using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
31
Steve Anton94286cb2017-09-26 23:20:1932namespace {
Steve Anton6f25b092017-10-23 16:39:2033const uint32_t kDefaultTimeout = 10000U;
Steve Anton94286cb2017-09-26 23:20:1934}
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 10:50:3340 : pc_factory_(std::move(pc_factory)),
41 observer_(std::move(observer)),
42 pc_(std::move(pc)) {
Steve Anton94286cb2017-09-26 23:20:1943 RTC_DCHECK(pc_factory_);
44 RTC_DCHECK(pc_);
45 RTC_DCHECK(observer_);
46 observer_->SetPeerConnectionInterface(pc_.get());
47}
48
Tomas Gunnarsson2efb8a52021-04-01 14:26:5749PeerConnectionWrapper::~PeerConnectionWrapper() {
50 if (pc_)
51 pc_->Close();
52}
Steve Anton94286cb2017-09-26 23:20:1953
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 21:58:0768 return CreateOffer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 23:20:1969}
70
71std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateOffer(
Steve Anton8d3444d2017-10-20 22:30:5172 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 23:20:1979}
80
81std::unique_ptr<SessionDescriptionInterface>
82PeerConnectionWrapper::CreateOfferAndSetAsLocal() {
Steve Anton22da89f2018-01-25 21:58:0783 return CreateOfferAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 22:30:5184}
85
86std::unique_ptr<SessionDescriptionInterface>
87PeerConnectionWrapper::CreateOfferAndSetAsLocal(
88 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
89 auto offer = CreateOffer(options);
Steve Anton94286cb2017-09-26 23:20:1990 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 21:58:0799 return CreateAnswer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 23:20:19100}
101
102std::unique_ptr<SessionDescriptionInterface>
103PeerConnectionWrapper::CreateAnswer(
Steve Anton8d3444d2017-10-20 22:30:51104 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 23:20:19111}
112
113std::unique_ptr<SessionDescriptionInterface>
114PeerConnectionWrapper::CreateAnswerAndSetAsLocal() {
Steve Anton22da89f2018-01-25 21:58:07115 return CreateAnswerAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 22:30:51116}
117
118std::unique_ptr<SessionDescriptionInterface>
119PeerConnectionWrapper::CreateAnswerAndSetAsLocal(
120 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
121 auto answer = CreateAnswer(options);
Steve Anton94286cb2017-09-26 23:20:19122 if (!answer) {
123 return nullptr;
124 }
125 EXPECT_TRUE(SetLocalDescription(CloneSessionDescription(answer.get())));
126 return answer;
127}
128
Eldar Rello5ab79e62019-10-09 15:29:44129std::unique_ptr<SessionDescriptionInterface>
130PeerConnectionWrapper::CreateRollback() {
131 return CreateSessionDescription(SdpType::kRollback, "");
132}
133
Steve Anton94286cb2017-09-26 23:20:19134std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateSdp(
Mirko Bonadei2a823102017-11-13 10:50:33135 rtc::FunctionView<void(CreateSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 22:30:51136 std::string* error_out) {
Tommi87f70902021-04-27 12:43:08137 auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 12:26:50138 fn(observer.get());
Steve Anton6f25b092017-10-23 16:39:20139 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 22:30:51140 if (error_out && !observer->result()) {
141 *error_out = observer->error();
142 }
Steve Anton94286cb2017-09-26 23:20:19143 return observer->MoveDescription();
144}
145
146bool PeerConnectionWrapper::SetLocalDescription(
Steve Anton8d3444d2017-10-20 22:30:51147 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 23:20:19154}
155
156bool PeerConnectionWrapper::SetRemoteDescription(
Steve Anton8d3444d2017-10-20 22:30:51157 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 23:20:19164}
165
Henrik Boström31638672017-11-23 16:48:32166bool PeerConnectionWrapper::SetRemoteDescription(
167 std::unique_ptr<SessionDescriptionInterface> desc,
168 RTCError* error_out) {
Niels Möllere7cc8832022-01-04 14:20:03169 auto observer = rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>();
Henrik Boström31638672017-11-23 16:48:32170 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 23:20:19178bool PeerConnectionWrapper::SetSdp(
Mirko Bonadei2a823102017-11-13 10:50:33179 rtc::FunctionView<void(SetSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 22:30:51180 std::string* error_out) {
Tommi87f70902021-04-27 12:43:08181 auto observer = rtc::make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 12:26:50182 fn(observer.get());
Steve Anton6f25b092017-10-23 16:39:20183 EXPECT_EQ_WAIT(true, observer->called(), kDefaultTimeout);
Steve Anton8d3444d2017-10-20 22:30:51184 if (error_out && !observer->result()) {
185 *error_out = observer->error();
Steve Anton94286cb2017-09-26 23:20:19186 }
187 return observer->result();
188}
189
Steve Antondcc3c022017-12-23 00:02:54190bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
191 PeerConnectionWrapper* answerer) {
Steve Anton22da89f2018-01-25 21:58:07192 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-23 00:02:54200 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 21:58:07205 auto offer = CreateOffer(offer_options);
Steve Antondcc3c022017-12-23 00:02:54206 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 21:58:07221 auto answer = answerer->CreateAnswer(answer_options);
Steve Antondcc3c022017-12-23 00:02:54222 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 21:01:52237rtc::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) {
Harald Alvestrand041ecb82023-03-20 14:13:42280 return pc_factory()->CreateVideoTrack(FakeVideoTrackSource::Create(), label);
Steve Anton9158ef62017-11-27 21:01:52281}
282
Steve Anton2d6c76a2018-01-06 01:10:52283rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
284 rtc::scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 19:34:10285 const std::vector<std::string>& stream_ids) {
Steve Anton2d6c76a2018-01-06 01:10:52286 RTCErrorOr<rtc::scoped_refptr<RtpSenderInterface>> result =
Seth Hampson845e8782018-03-02 19:34:10287 pc()->AddTrack(track, stream_ids);
Steve Anton2d6c76a2018-01-06 01:10:52288 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
289 return result.MoveValue();
290}
291
Jonas Oreland4b2a1062022-10-19 07:24:42292rtc::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 22:30:51302rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddAudioTrack(
303 const std::string& track_label,
Seth Hampson845e8782018-03-02 19:34:10304 const std::vector<std::string>& stream_ids) {
305 return AddTrack(CreateAudioTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 23:20:19306}
307
Steve Anton8d3444d2017-10-20 22:30:51308rtc::scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddVideoTrack(
309 const std::string& track_label,
Seth Hampson845e8782018-03-02 19:34:10310 const std::vector<std::string>& stream_ids) {
311 return AddTrack(CreateVideoTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 23:20:19312}
313
Steve Antonfa2260d2017-12-29 00:38:23314rtc::scoped_refptr<DataChannelInterface>
Jeremy Leconteeccd93e2023-02-10 08:26:50315PeerConnectionWrapper::CreateDataChannel(
316 const std::string& label,
317 const absl::optional<DataChannelInit>& config) {
318 const DataChannelInit* config_ptr = config.has_value() ? &(*config) : nullptr;
319 auto result = pc()->CreateDataChannelOrError(label, config_ptr);
Harald Alvestranda9af50f2021-05-21 13:33:51320 if (!result.ok()) {
321 RTC_LOG(LS_ERROR) << "CreateDataChannel failed: "
322 << ToString(result.error().type()) << " "
323 << result.error().message();
324 return nullptr;
325 }
326 return result.MoveValue();
Steve Antonfa2260d2017-12-29 00:38:23327}
328
Steve Anton8d3444d2017-10-20 22:30:51329PeerConnectionInterface::SignalingState
330PeerConnectionWrapper::signaling_state() {
331 return pc()->signaling_state();
Steve Anton94286cb2017-09-26 23:20:19332}
333
Steve Antonf1c6db12017-10-13 18:13:35334bool PeerConnectionWrapper::IsIceGatheringDone() {
Steve Anton6f25b092017-10-23 16:39:20335 return observer()->ice_gathering_complete_;
336}
337
338bool PeerConnectionWrapper::IsIceConnected() {
339 return observer()->ice_connected_;
340}
341
Harald Alvestranda6544372023-11-13 09:33:56342rtc::scoped_refptr<const RTCStatsReport> PeerConnectionWrapper::GetStats() {
Tommi87f70902021-04-27 12:43:08343 auto callback = rtc::make_ref_counted<MockRTCStatsCollectorCallback>();
Niels Möllerafb246b2022-04-20 12:26:50344 pc()->GetStats(callback.get());
Steve Anton6f25b092017-10-23 16:39:20345 EXPECT_TRUE_WAIT(callback->called(), kDefaultTimeout);
346 return callback->report();
Steve Antonf1c6db12017-10-13 18:13:35347}
348
Steve Anton94286cb2017-09-26 23:20:19349} // namespace webrtc