Thanks to visit codestin.com
Credit goes to webrtc.googlesource.com

blob: 3c21208844556760ac4cf2937d5442c8a472690c [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
Evan Shrubsole3e8e4782025-01-08 11:30:3113#include <memory>
Florent Castelli8037fc62024-08-29 13:00:4014#include <optional>
Evan Shrubsole3e8e4782025-01-08 11:30:3115#include <string>
Steve Anton94286cb2017-09-26 23:20:1916#include <utility>
Steve Anton36b29d12017-10-30 16:57:4217#include <vector>
Steve Anton94286cb2017-09-26 23:20:1918
Evan Shrubsole3e8e4782025-01-08 11:30:3119#include "api/data_channel_interface.h"
Artem Titov741daaf2019-03-21 13:37:3620#include "api/function_view.h"
Evan Shrubsole3e8e4782025-01-08 11:30:3121#include "api/jsep.h"
22#include "api/make_ref_counted.h"
23#include "api/media_stream_interface.h"
24#include "api/media_types.h"
25#include "api/peer_connection_interface.h"
26#include "api/rtc_error.h"
27#include "api/rtp_parameters.h"
28#include "api/rtp_sender_interface.h"
29#include "api/rtp_transceiver_interface.h"
30#include "api/scoped_refptr.h"
31#include "api/stats/rtc_stats_report.h"
32#include "api/test/rtc_error_matchers.h"
Danil Chapovalovb1ec8132025-02-04 16:50:4433#include "pc/peer_connection.h"
34#include "pc/peer_connection_proxy.h"
Steve Anton10542f22019-01-11 17:11:0035#include "pc/test/fake_video_track_source.h"
Evan Shrubsole3e8e4782025-01-08 11:30:3136#include "pc/test/mock_peer_connection_observers.h"
Yves Gerey3e707812018-11-28 15:47:4937#include "rtc_base/checks.h"
Yves Gerey3e707812018-11-28 15:47:4938#include "rtc_base/logging.h"
Evan Shrubsole3e8e4782025-01-08 11:30:3139#include "test/gmock.h"
Yves Gerey3e707812018-11-28 15:47:4940#include "test/gtest.h"
Evan Shrubsole3e8e4782025-01-08 11:30:3141#include "test/wait_until.h"
Steve Anton94286cb2017-09-26 23:20:1942
43namespace webrtc {
44
Philipp Hanckecfaba8f2025-01-15 01:16:3945using ::testing::Eq;
Steve Anton22da89f2018-01-25 21:58:0746using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
47
Steve Anton94286cb2017-09-26 23:20:1948PeerConnectionWrapper::PeerConnectionWrapper(
Evan Shrubsolee6a1f702025-04-15 14:55:4249 scoped_refptr<PeerConnectionFactoryInterface> pc_factory,
50 scoped_refptr<PeerConnectionInterface> pc,
Steve Anton94286cb2017-09-26 23:20:1951 std::unique_ptr<MockPeerConnectionObserver> observer)
Mirko Bonadei2a823102017-11-13 10:50:3352 : pc_factory_(std::move(pc_factory)),
53 observer_(std::move(observer)),
54 pc_(std::move(pc)) {
Steve Anton94286cb2017-09-26 23:20:1955 RTC_DCHECK(pc_factory_);
56 RTC_DCHECK(pc_);
57 RTC_DCHECK(observer_);
58 observer_->SetPeerConnectionInterface(pc_.get());
59}
60
Tomas Gunnarsson2efb8a52021-04-01 14:26:5761PeerConnectionWrapper::~PeerConnectionWrapper() {
62 if (pc_)
63 pc_->Close();
64}
Steve Anton94286cb2017-09-26 23:20:1965
66PeerConnectionFactoryInterface* PeerConnectionWrapper::pc_factory() {
67 return pc_factory_.get();
68}
69
70PeerConnectionInterface* PeerConnectionWrapper::pc() {
71 return pc_.get();
72}
73
74MockPeerConnectionObserver* PeerConnectionWrapper::observer() {
75 return observer_.get();
76}
77
Danil Chapovalovb1ec8132025-02-04 16:50:4478PeerConnection* PeerConnectionWrapper::GetInternalPeerConnection() {
79 auto* pci =
80 static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
81 pc());
82 return static_cast<PeerConnection*>(pci->internal());
83}
84
Steve Anton94286cb2017-09-26 23:20:1985std::unique_ptr<SessionDescriptionInterface>
86PeerConnectionWrapper::CreateOffer() {
Steve Anton22da89f2018-01-25 21:58:0787 return CreateOffer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 23:20:1988}
89
90std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateOffer(
Steve Anton8d3444d2017-10-20 22:30:5191 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
92 std::string* error_out) {
93 return CreateSdp(
94 [this, options](CreateSessionDescriptionObserver* observer) {
95 pc()->CreateOffer(observer, options);
96 },
97 error_out);
Steve Anton94286cb2017-09-26 23:20:1998}
99
100std::unique_ptr<SessionDescriptionInterface>
101PeerConnectionWrapper::CreateOfferAndSetAsLocal() {
Steve Anton22da89f2018-01-25 21:58:07102 return CreateOfferAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 22:30:51103}
104
105std::unique_ptr<SessionDescriptionInterface>
106PeerConnectionWrapper::CreateOfferAndSetAsLocal(
107 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
Philipp Hancked72cc2f2025-07-01 18:24:07108 std::unique_ptr<SessionDescriptionInterface> offer = CreateOffer(options);
Steve Anton94286cb2017-09-26 23:20:19109 if (!offer) {
110 return nullptr;
111 }
Harald Alvestrandf94ebc72025-10-08 12:31:10112 EXPECT_TRUE(SetLocalDescription(offer->Clone()));
Steve Anton94286cb2017-09-26 23:20:19113 return offer;
114}
115
116std::unique_ptr<SessionDescriptionInterface>
117PeerConnectionWrapper::CreateAnswer() {
Steve Anton22da89f2018-01-25 21:58:07118 return CreateAnswer(RTCOfferAnswerOptions());
Steve Anton94286cb2017-09-26 23:20:19119}
120
121std::unique_ptr<SessionDescriptionInterface>
122PeerConnectionWrapper::CreateAnswer(
Steve Anton8d3444d2017-10-20 22:30:51123 const PeerConnectionInterface::RTCOfferAnswerOptions& options,
124 std::string* error_out) {
125 return CreateSdp(
126 [this, options](CreateSessionDescriptionObserver* observer) {
127 pc()->CreateAnswer(observer, options);
128 },
129 error_out);
Steve Anton94286cb2017-09-26 23:20:19130}
131
132std::unique_ptr<SessionDescriptionInterface>
133PeerConnectionWrapper::CreateAnswerAndSetAsLocal() {
Steve Anton22da89f2018-01-25 21:58:07134 return CreateAnswerAndSetAsLocal(RTCOfferAnswerOptions());
Steve Anton8d3444d2017-10-20 22:30:51135}
136
137std::unique_ptr<SessionDescriptionInterface>
138PeerConnectionWrapper::CreateAnswerAndSetAsLocal(
139 const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
Philipp Hancked72cc2f2025-07-01 18:24:07140 std::unique_ptr<SessionDescriptionInterface> answer = CreateAnswer(options);
Steve Anton94286cb2017-09-26 23:20:19141 if (!answer) {
142 return nullptr;
143 }
Harald Alvestrandf94ebc72025-10-08 12:31:10144 EXPECT_TRUE(SetLocalDescription(answer->Clone()));
Steve Anton94286cb2017-09-26 23:20:19145 return answer;
146}
147
Eldar Rello5ab79e62019-10-09 15:29:44148std::unique_ptr<SessionDescriptionInterface>
149PeerConnectionWrapper::CreateRollback() {
Tommi7a191b12025-09-08 10:50:05150 return CreateRollbackSessionDescription();
Eldar Rello5ab79e62019-10-09 15:29:44151}
152
Steve Anton94286cb2017-09-26 23:20:19153std::unique_ptr<SessionDescriptionInterface> PeerConnectionWrapper::CreateSdp(
Evan Shrubsole97feff22025-03-12 09:13:45154 FunctionView<void(CreateSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 22:30:51155 std::string* error_out) {
Evan Shrubsolee6a1f702025-04-15 14:55:42156 auto observer = make_ref_counted<MockCreateSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 12:26:50157 fn(observer.get());
Evan Shrubsole3e8e4782025-01-08 11:30:31158 EXPECT_THAT(
159 WaitUntil([&] { return observer->called(); }, ::testing::IsTrue()),
160 IsRtcOk());
Steve Anton8d3444d2017-10-20 22:30:51161 if (error_out && !observer->result()) {
162 *error_out = observer->error();
163 }
Steve Anton94286cb2017-09-26 23:20:19164 return observer->MoveDescription();
165}
166
167bool PeerConnectionWrapper::SetLocalDescription(
Steve Anton8d3444d2017-10-20 22:30:51168 std::unique_ptr<SessionDescriptionInterface> desc,
169 std::string* error_out) {
170 return SetSdp(
171 [this, &desc](SetSessionDescriptionObserver* observer) {
172 pc()->SetLocalDescription(observer, desc.release());
173 },
174 error_out);
Steve Anton94286cb2017-09-26 23:20:19175}
176
Philipp Hanckecfaba8f2025-01-15 01:16:39177bool PeerConnectionWrapper::SetLocalDescription(
178 std::unique_ptr<SessionDescriptionInterface> desc,
179 RTCError* error_out) {
Evan Shrubsolee6a1f702025-04-15 14:55:42180 auto observer = make_ref_counted<FakeSetLocalDescriptionObserver>();
Philipp Hanckecfaba8f2025-01-15 01:16:39181 pc()->SetLocalDescription(std::move(desc), observer);
182 EXPECT_THAT(
183 WaitUntil([&] { return observer->called(); }, ::testing::IsTrue()),
184 IsRtcOk());
185 bool ok = observer->error().ok();
186 if (error_out)
187 *error_out = std::move(observer->error());
188 return ok;
189}
190
Steve Anton94286cb2017-09-26 23:20:19191bool PeerConnectionWrapper::SetRemoteDescription(
Steve Anton8d3444d2017-10-20 22:30:51192 std::unique_ptr<SessionDescriptionInterface> desc,
193 std::string* error_out) {
194 return SetSdp(
195 [this, &desc](SetSessionDescriptionObserver* observer) {
196 pc()->SetRemoteDescription(observer, desc.release());
197 },
198 error_out);
Steve Anton94286cb2017-09-26 23:20:19199}
200
Henrik Boström31638672017-11-23 16:48:32201bool PeerConnectionWrapper::SetRemoteDescription(
202 std::unique_ptr<SessionDescriptionInterface> desc,
203 RTCError* error_out) {
Evan Shrubsolee6a1f702025-04-15 14:55:42204 auto observer = make_ref_counted<FakeSetRemoteDescriptionObserver>();
Henrik Boström31638672017-11-23 16:48:32205 pc()->SetRemoteDescription(std::move(desc), observer);
Evan Shrubsole3e8e4782025-01-08 11:30:31206 EXPECT_THAT(
207 WaitUntil([&] { return observer->called(); }, ::testing::IsTrue()),
208 IsRtcOk());
Henrik Boström31638672017-11-23 16:48:32209 bool ok = observer->error().ok();
210 if (error_out)
211 *error_out = std::move(observer->error());
212 return ok;
213}
214
Steve Anton94286cb2017-09-26 23:20:19215bool PeerConnectionWrapper::SetSdp(
Evan Shrubsole97feff22025-03-12 09:13:45216 FunctionView<void(SetSessionDescriptionObserver*)> fn,
Steve Anton8d3444d2017-10-20 22:30:51217 std::string* error_out) {
Evan Shrubsolee6a1f702025-04-15 14:55:42218 auto observer = make_ref_counted<MockSetSessionDescriptionObserver>();
Niels Möllerafb246b2022-04-20 12:26:50219 fn(observer.get());
Evan Shrubsole3e8e4782025-01-08 11:30:31220 EXPECT_THAT(
221 WaitUntil([&] { return observer->called(); }, ::testing::IsTrue()),
222 IsRtcOk());
Steve Anton8d3444d2017-10-20 22:30:51223 if (error_out && !observer->result()) {
224 *error_out = observer->error();
Steve Anton94286cb2017-09-26 23:20:19225 }
226 return observer->result();
227}
228
Steve Antondcc3c022017-12-23 00:02:54229bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
230 PeerConnectionWrapper* answerer) {
Steve Anton22da89f2018-01-25 21:58:07231 return ExchangeOfferAnswerWith(answerer, RTCOfferAnswerOptions(),
232 RTCOfferAnswerOptions());
233}
234
235bool PeerConnectionWrapper::ExchangeOfferAnswerWith(
236 PeerConnectionWrapper* answerer,
237 const PeerConnectionInterface::RTCOfferAnswerOptions& offer_options,
238 const PeerConnectionInterface::RTCOfferAnswerOptions& answer_options) {
Steve Antondcc3c022017-12-23 00:02:54239 RTC_DCHECK(answerer);
240 if (answerer == this) {
241 RTC_LOG(LS_ERROR) << "Cannot exchange offer/answer with ourself!";
242 return false;
243 }
Philipp Hancked72cc2f2025-07-01 18:24:07244 std::unique_ptr<SessionDescriptionInterface> offer =
245 CreateOffer(offer_options);
Steve Antondcc3c022017-12-23 00:02:54246 EXPECT_TRUE(offer);
247 if (!offer) {
248 return false;
249 }
Harald Alvestrandf94ebc72025-10-08 12:31:10250 bool set_local_offer = SetLocalDescription(offer->Clone());
Steve Antondcc3c022017-12-23 00:02:54251 EXPECT_TRUE(set_local_offer);
252 if (!set_local_offer) {
253 return false;
254 }
255 bool set_remote_offer = answerer->SetRemoteDescription(std::move(offer));
256 EXPECT_TRUE(set_remote_offer);
257 if (!set_remote_offer) {
258 return false;
259 }
Philipp Hancked72cc2f2025-07-01 18:24:07260 std::unique_ptr<SessionDescriptionInterface> answer =
261 answerer->CreateAnswer(answer_options);
Steve Antondcc3c022017-12-23 00:02:54262 EXPECT_TRUE(answer);
263 if (!answer) {
264 return false;
265 }
Harald Alvestrandf94ebc72025-10-08 12:31:10266 bool set_local_answer = answerer->SetLocalDescription(answer->Clone());
Steve Antondcc3c022017-12-23 00:02:54267 EXPECT_TRUE(set_local_answer);
268 if (!set_local_answer) {
269 return false;
270 }
271 bool set_remote_answer = SetRemoteDescription(std::move(answer));
272 EXPECT_TRUE(set_remote_answer);
273 return set_remote_answer;
274}
275
Evan Shrubsolee6a1f702025-04-15 14:55:42276scoped_refptr<RtpTransceiverInterface> PeerConnectionWrapper::AddTransceiver(
Evan Shrubsole94adaee2025-05-09 10:35:15277 MediaType media_type) {
Evan Shrubsolee6a1f702025-04-15 14:55:42278 RTCErrorOr<scoped_refptr<RtpTransceiverInterface>> result =
Steve Anton9158ef62017-11-27 21:01:52279 pc()->AddTransceiver(media_type);
280 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
281 return result.MoveValue();
282}
283
Evan Shrubsolee6a1f702025-04-15 14:55:42284scoped_refptr<RtpTransceiverInterface> PeerConnectionWrapper::AddTransceiver(
Evan Shrubsole94adaee2025-05-09 10:35:15285 MediaType media_type,
Evan Shrubsolee6a1f702025-04-15 14:55:42286 const RtpTransceiverInit& init) {
287 RTCErrorOr<scoped_refptr<RtpTransceiverInterface>> result =
Steve Anton9158ef62017-11-27 21:01:52288 pc()->AddTransceiver(media_type, init);
289 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
290 return result.MoveValue();
291}
292
Evan Shrubsolee6a1f702025-04-15 14:55:42293scoped_refptr<RtpTransceiverInterface> PeerConnectionWrapper::AddTransceiver(
294 scoped_refptr<MediaStreamTrackInterface> track) {
295 RTCErrorOr<scoped_refptr<RtpTransceiverInterface>> result =
Steve Anton9158ef62017-11-27 21:01:52296 pc()->AddTransceiver(track);
297 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
298 return result.MoveValue();
299}
300
Evan Shrubsolee6a1f702025-04-15 14:55:42301scoped_refptr<RtpTransceiverInterface> PeerConnectionWrapper::AddTransceiver(
302 scoped_refptr<MediaStreamTrackInterface> track,
Steve Anton9158ef62017-11-27 21:01:52303 const RtpTransceiverInit& init) {
Evan Shrubsolee6a1f702025-04-15 14:55:42304 RTCErrorOr<scoped_refptr<RtpTransceiverInterface>> result =
Steve Anton9158ef62017-11-27 21:01:52305 pc()->AddTransceiver(track, init);
306 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
307 return result.MoveValue();
308}
309
Evan Shrubsolee6a1f702025-04-15 14:55:42310scoped_refptr<AudioTrackInterface> PeerConnectionWrapper::CreateAudioTrack(
Steve Anton9158ef62017-11-27 21:01:52311 const std::string& label) {
312 return pc_factory()->CreateAudioTrack(label, nullptr);
313}
314
Evan Shrubsolee6a1f702025-04-15 14:55:42315scoped_refptr<VideoTrackInterface> PeerConnectionWrapper::CreateVideoTrack(
Steve Anton9158ef62017-11-27 21:01:52316 const std::string& label) {
Harald Alvestrand041ecb82023-03-20 14:13:42317 return pc_factory()->CreateVideoTrack(FakeVideoTrackSource::Create(), label);
Steve Anton9158ef62017-11-27 21:01:52318}
319
Evan Shrubsolee6a1f702025-04-15 14:55:42320scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
321 scoped_refptr<MediaStreamTrackInterface> track,
Seth Hampson845e8782018-03-02 19:34:10322 const std::vector<std::string>& stream_ids) {
Evan Shrubsolee6a1f702025-04-15 14:55:42323 RTCErrorOr<scoped_refptr<RtpSenderInterface>> result =
Seth Hampson845e8782018-03-02 19:34:10324 pc()->AddTrack(track, stream_ids);
Steve Anton2d6c76a2018-01-06 01:10:52325 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
326 return result.MoveValue();
327}
328
Evan Shrubsolee6a1f702025-04-15 14:55:42329scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddTrack(
330 scoped_refptr<MediaStreamTrackInterface> track,
Jonas Oreland4b2a1062022-10-19 07:24:42331 const std::vector<std::string>& stream_ids,
332 const std::vector<RtpEncodingParameters>& init_send_encodings) {
Evan Shrubsolee6a1f702025-04-15 14:55:42333 RTCErrorOr<scoped_refptr<RtpSenderInterface>> result =
Jonas Oreland4b2a1062022-10-19 07:24:42334 pc()->AddTrack(track, stream_ids, init_send_encodings);
335 EXPECT_EQ(RTCErrorType::NONE, result.error().type());
336 return result.MoveValue();
337}
338
Evan Shrubsolee6a1f702025-04-15 14:55:42339scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddAudioTrack(
Steve Anton8d3444d2017-10-20 22:30:51340 const std::string& track_label,
Seth Hampson845e8782018-03-02 19:34:10341 const std::vector<std::string>& stream_ids) {
342 return AddTrack(CreateAudioTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 23:20:19343}
344
Evan Shrubsolee6a1f702025-04-15 14:55:42345scoped_refptr<RtpSenderInterface> PeerConnectionWrapper::AddVideoTrack(
Steve Anton8d3444d2017-10-20 22:30:51346 const std::string& track_label,
Seth Hampson845e8782018-03-02 19:34:10347 const std::vector<std::string>& stream_ids) {
348 return AddTrack(CreateVideoTrack(track_label), stream_ids);
Steve Anton94286cb2017-09-26 23:20:19349}
350
Evan Shrubsolee6a1f702025-04-15 14:55:42351scoped_refptr<DataChannelInterface> PeerConnectionWrapper::CreateDataChannel(
Jeremy Leconteeccd93e2023-02-10 08:26:50352 const std::string& label,
Florent Castelli8037fc62024-08-29 13:00:40353 const std::optional<DataChannelInit>& config) {
Jeremy Leconteeccd93e2023-02-10 08:26:50354 const DataChannelInit* config_ptr = config.has_value() ? &(*config) : nullptr;
355 auto result = pc()->CreateDataChannelOrError(label, config_ptr);
Harald Alvestranda9af50f2021-05-21 13:33:51356 if (!result.ok()) {
357 RTC_LOG(LS_ERROR) << "CreateDataChannel failed: "
358 << ToString(result.error().type()) << " "
359 << result.error().message();
360 return nullptr;
361 }
362 return result.MoveValue();
Steve Antonfa2260d2017-12-29 00:38:23363}
364
Steve Anton8d3444d2017-10-20 22:30:51365PeerConnectionInterface::SignalingState
366PeerConnectionWrapper::signaling_state() {
367 return pc()->signaling_state();
Steve Anton94286cb2017-09-26 23:20:19368}
369
Steve Antonf1c6db12017-10-13 18:13:35370bool PeerConnectionWrapper::IsIceGatheringDone() {
Steve Anton6f25b092017-10-23 16:39:20371 return observer()->ice_gathering_complete_;
372}
373
374bool PeerConnectionWrapper::IsIceConnected() {
375 return observer()->ice_connected_;
376}
377
Evan Shrubsolee6a1f702025-04-15 14:55:42378scoped_refptr<const RTCStatsReport> PeerConnectionWrapper::GetStats() {
379 auto callback = make_ref_counted<MockRTCStatsCollectorCallback>();
Niels Möllerafb246b2022-04-20 12:26:50380 pc()->GetStats(callback.get());
Evan Shrubsole3e8e4782025-01-08 11:30:31381 EXPECT_THAT(
382 WaitUntil([&] { return callback->called(); }, ::testing::IsTrue()),
383 IsRtcOk());
Steve Anton6f25b092017-10-23 16:39:20384 return callback->report();
Steve Antonf1c6db12017-10-13 18:13:35385}
386
Steve Anton94286cb2017-09-26 23:20:19387} // namespace webrtc