blob: 67d0ff0cd67347dd584e9a2f04c53970467266a1 [file] [log] [blame]
hjonf396f602016-02-11 16:19:06 -08001/*
2 * Copyright 2015 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
tkchin9eeb6242016-04-27 01:54:20 -070011#import "RTCPeerConnection+Private.h"
12
tkchin9eeb6242016-04-27 01:54:20 -070013#import "RTCConfiguration+Private.h"
14#import "RTCDataChannel+Private.h"
15#import "RTCIceCandidate+Private.h"
hbosbd3dda62016-09-09 01:36:28 -070016#import "RTCLegacyStatsReport+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070017#import "RTCMediaConstraints+Private.h"
18#import "RTCMediaStream+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080019#import "RTCMediaStreamTrack+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070020#import "RTCPeerConnectionFactory+Private.h"
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -070021#import "RTCRtpReceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070022#import "RTCRtpSender+Private.h"
Steve Anton8cb344a2018-02-27 15:34:53 -080023#import "RTCRtpTransceiver+Private.h"
tkchin9eeb6242016-04-27 01:54:20 -070024#import "RTCSessionDescription+Private.h"
Anders Carlsson7bca8ca2018-08-30 09:30:29 +020025#import "base/RTCLogging.h"
26#import "helpers/NSString+StdString.h"
hjonf396f602016-02-11 16:19:06 -080027
kwibergbfefb032016-05-01 14:53:46 -070028#include <memory>
29
Steve Anton10542f22019-01-11 09:11:00 -080030#include "api/jsep_ice_candidate.h"
Niels Möller695cf6a2019-05-13 12:27:23 +020031#include "api/rtc_event_log_output_file.h"
Yura Yaroshevichd6725352021-03-05 18:21:16 +030032#include "api/set_local_description_observer_interface.h"
33#include "api/set_remote_description_observer_interface.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020034#include "rtc_base/checks.h"
Niels Möller695cf6a2019-05-13 12:27:23 +020035#include "rtc_base/numerics/safe_conversions.h"
hjonf396f602016-02-11 16:19:06 -080036
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020037NSString *const kRTCPeerConnectionErrorDomain = @"org.webrtc.RTC_OBJC_TYPE(RTCPeerConnection)";
hjonf396f602016-02-11 16:19:06 -080038int const kRTCPeerConnnectionSessionDescriptionError = -1;
39
Yura Yaroshevichd6725352021-03-05 18:21:16 +030040namespace {
41
42class SetSessionDescriptionObserver : public webrtc::SetLocalDescriptionObserverInterface,
43 public webrtc::SetRemoteDescriptionObserverInterface {
44 public:
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030045 SetSessionDescriptionObserver(RTCSetSessionDescriptionCompletionHandler completionHandler) {
Yura Yaroshevichd6725352021-03-05 18:21:16 +030046 completion_handler_ = completionHandler;
47 }
48
49 virtual void OnSetLocalDescriptionComplete(webrtc::RTCError error) override {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030050 OnCompelete(error);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030051 }
52
53 virtual void OnSetRemoteDescriptionComplete(webrtc::RTCError error) override {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030054 OnCompelete(error);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030055 }
56
57 private:
58 void OnCompelete(webrtc::RTCError error) {
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +030059 RTC_DCHECK(completion_handler_ != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +030060 if (error.ok()) {
61 completion_handler_(nil);
62 } else {
63 // TODO(hta): Add handling of error.type()
64 NSString *str = [NSString stringForStdString:error.message()];
65 NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
66 code:kRTCPeerConnnectionSessionDescriptionError
67 userInfo:@{NSLocalizedDescriptionKey : str}];
68 completion_handler_(err);
69 }
70 completion_handler_ = nil;
71 }
72 RTCSetSessionDescriptionCompletionHandler completion_handler_;
73};
74
75} // anonymous namespace
76
hjonf396f602016-02-11 16:19:06 -080077namespace webrtc {
78
79class CreateSessionDescriptionObserverAdapter
80 : public CreateSessionDescriptionObserver {
81 public:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020082 CreateSessionDescriptionObserverAdapter(void (^completionHandler)(
83 RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription, NSError *error)) {
hjonf396f602016-02-11 16:19:06 -080084 completion_handler_ = completionHandler;
85 }
86
Mirko Bonadei17aff352018-07-26 12:20:40 +020087 ~CreateSessionDescriptionObserverAdapter() override { completion_handler_ = nil; }
hjonf396f602016-02-11 16:19:06 -080088
89 void OnSuccess(SessionDescriptionInterface *desc) override {
90 RTC_DCHECK(completion_handler_);
kwibergbfefb032016-05-01 14:53:46 -070091 std::unique_ptr<webrtc::SessionDescriptionInterface> description =
92 std::unique_ptr<webrtc::SessionDescriptionInterface>(desc);
Mirko Bonadeia81e9c82020-05-04 16:14:32 +020093 RTC_OBJC_TYPE(RTCSessionDescription) *session =
94 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description.get()];
hjonf396f602016-02-11 16:19:06 -080095 completion_handler_(session, nil);
96 completion_handler_ = nil;
97 }
98
Harald Alvestrand73771a82018-05-24 10:53:49 +020099 void OnFailure(RTCError error) override {
hjonf396f602016-02-11 16:19:06 -0800100 RTC_DCHECK(completion_handler_);
Harald Alvestrand73771a82018-05-24 10:53:49 +0200101 // TODO(hta): Add handling of error.type()
102 NSString *str = [NSString stringForStdString:error.message()];
hjonf396f602016-02-11 16:19:06 -0800103 NSError* err =
104 [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
105 code:kRTCPeerConnnectionSessionDescriptionError
106 userInfo:@{ NSLocalizedDescriptionKey : str }];
107 completion_handler_(nil, err);
108 completion_handler_ = nil;
109 }
110
111 private:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200112 void (^completion_handler_)(RTC_OBJC_TYPE(RTCSessionDescription) * sessionDescription,
113 NSError *error);
hjonf396f602016-02-11 16:19:06 -0800114};
115
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200116PeerConnectionDelegateAdapter::PeerConnectionDelegateAdapter(RTC_OBJC_TYPE(RTCPeerConnection) *
117 peerConnection) {
hjonf396f602016-02-11 16:19:06 -0800118 peer_connection_ = peerConnection;
119}
120
121PeerConnectionDelegateAdapter::~PeerConnectionDelegateAdapter() {
122 peer_connection_ = nil;
123}
124
125void PeerConnectionDelegateAdapter::OnSignalingChange(
126 PeerConnectionInterface::SignalingState new_state) {
127 RTCSignalingState state =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200128 [[RTC_OBJC_TYPE(RTCPeerConnection) class] signalingStateForNativeState:new_state];
129 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800130 [peer_connection.delegate peerConnection:peer_connection
131 didChangeSignalingState:state];
132}
133
134void PeerConnectionDelegateAdapter::OnAddStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700135 rtc::scoped_refptr<MediaStreamInterface> stream) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200136 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
137 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
138 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
139 nativeMediaStream:stream];
hjonf396f602016-02-11 16:19:06 -0800140 [peer_connection.delegate peerConnection:peer_connection
141 didAddStream:mediaStream];
142}
143
144void PeerConnectionDelegateAdapter::OnRemoveStream(
deadbeefd5f41ce2016-06-08 13:31:45 -0700145 rtc::scoped_refptr<MediaStreamInterface> stream) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200146 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
147 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
148 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
149 nativeMediaStream:stream];
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300150
hjonf396f602016-02-11 16:19:06 -0800151 [peer_connection.delegate peerConnection:peer_connection
152 didRemoveStream:mediaStream];
153}
154
Steve Anton8cb344a2018-02-27 15:34:53 -0800155void PeerConnectionDelegateAdapter::OnTrack(
156 rtc::scoped_refptr<RtpTransceiverInterface> nativeTransceiver) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200157 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
158 RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
159 [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:peer_connection.factory
160 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800161 if ([peer_connection.delegate
162 respondsToSelector:@selector(peerConnection:didStartReceivingOnTransceiver:)]) {
163 [peer_connection.delegate peerConnection:peer_connection
164 didStartReceivingOnTransceiver:transceiver];
165 }
166}
167
hjonf396f602016-02-11 16:19:06 -0800168void PeerConnectionDelegateAdapter::OnDataChannel(
deadbeefd5f41ce2016-06-08 13:31:45 -0700169 rtc::scoped_refptr<DataChannelInterface> data_channel) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200170 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
171 RTC_OBJC_TYPE(RTCDataChannel) *dataChannel =
172 [[RTC_OBJC_TYPE(RTCDataChannel) alloc] initWithFactory:peer_connection.factory
173 nativeDataChannel:data_channel];
hjonf396f602016-02-11 16:19:06 -0800174 [peer_connection.delegate peerConnection:peer_connection
175 didOpenDataChannel:dataChannel];
176}
177
178void PeerConnectionDelegateAdapter::OnRenegotiationNeeded() {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200179 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800180 [peer_connection.delegate peerConnectionShouldNegotiate:peer_connection];
181}
182
183void PeerConnectionDelegateAdapter::OnIceConnectionChange(
184 PeerConnectionInterface::IceConnectionState new_state) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200185 RTCIceConnectionState state =
186 [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state];
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100187 [peer_connection_.delegate peerConnection:peer_connection_ didChangeIceConnectionState:state];
188}
189
Qingsi Wang36e31472019-05-29 11:37:26 -0700190void PeerConnectionDelegateAdapter::OnStandardizedIceConnectionChange(
191 PeerConnectionInterface::IceConnectionState new_state) {
192 if ([peer_connection_.delegate
193 respondsToSelector:@selector(peerConnection:didChangeStandardizedIceConnectionState:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200194 RTCIceConnectionState state =
195 [RTC_OBJC_TYPE(RTCPeerConnection) iceConnectionStateForNativeState:new_state];
Qingsi Wang36e31472019-05-29 11:37:26 -0700196 [peer_connection_.delegate peerConnection:peer_connection_
197 didChangeStandardizedIceConnectionState:state];
198 }
199}
200
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100201void PeerConnectionDelegateAdapter::OnConnectionChange(
202 PeerConnectionInterface::PeerConnectionState new_state) {
203 if ([peer_connection_.delegate
204 respondsToSelector:@selector(peerConnection:didChangeConnectionState:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200205 RTCPeerConnectionState state =
206 [RTC_OBJC_TYPE(RTCPeerConnection) connectionStateForNativeState:new_state];
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100207 [peer_connection_.delegate peerConnection:peer_connection_ didChangeConnectionState:state];
208 }
hjonf396f602016-02-11 16:19:06 -0800209}
210
211void PeerConnectionDelegateAdapter::OnIceGatheringChange(
212 PeerConnectionInterface::IceGatheringState new_state) {
213 RTCIceGatheringState state =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200214 [[RTC_OBJC_TYPE(RTCPeerConnection) class] iceGatheringStateForNativeState:new_state];
215 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800216 [peer_connection.delegate peerConnection:peer_connection
217 didChangeIceGatheringState:state];
218}
219
220void PeerConnectionDelegateAdapter::OnIceCandidate(
221 const IceCandidateInterface *candidate) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200222 RTC_OBJC_TYPE(RTCIceCandidate) *iceCandidate =
223 [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate];
224 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
hjonf396f602016-02-11 16:19:06 -0800225 [peer_connection.delegate peerConnection:peer_connection
226 didGenerateIceCandidate:iceCandidate];
227}
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700228
229void PeerConnectionDelegateAdapter::OnIceCandidatesRemoved(
230 const std::vector<cricket::Candidate>& candidates) {
231 NSMutableArray* ice_candidates =
232 [NSMutableArray arrayWithCapacity:candidates.size()];
233 for (const auto& candidate : candidates) {
234 std::unique_ptr<JsepIceCandidate> candidate_wrapper(
235 new JsepIceCandidate(candidate.transport_name(), -1, candidate));
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200236 RTC_OBJC_TYPE(RTCIceCandidate) *ice_candidate =
237 [[RTC_OBJC_TYPE(RTCIceCandidate) alloc] initWithNativeCandidate:candidate_wrapper.get()];
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700238 [ice_candidates addObject:ice_candidate];
239 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200240 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700241 [peer_connection.delegate peerConnection:peer_connection
242 didRemoveIceCandidates:ice_candidates];
243}
244
Alex Drake43faee02019-08-12 16:27:34 -0700245void PeerConnectionDelegateAdapter::OnIceSelectedCandidatePairChanged(
246 const cricket::CandidatePairChangeEvent &event) {
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700247 const auto &selected_pair = event.selected_candidate_pair;
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200248 auto local_candidate_wrapper = std::make_unique<JsepIceCandidate>(
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700249 selected_pair.local_candidate().transport_name(), -1, selected_pair.local_candidate());
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200250 RTC_OBJC_TYPE(RTCIceCandidate) *local_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
251 initWithNativeCandidate:local_candidate_wrapper.release()];
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200252 auto remote_candidate_wrapper = std::make_unique<JsepIceCandidate>(
Qingsi Wang7cdcda92019-08-28 09:18:37 -0700253 selected_pair.remote_candidate().transport_name(), -1, selected_pair.remote_candidate());
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200254 RTC_OBJC_TYPE(RTCIceCandidate) *remote_candidate = [[RTC_OBJC_TYPE(RTCIceCandidate) alloc]
255 initWithNativeCandidate:remote_candidate_wrapper.release()];
256 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Alex Drake43faee02019-08-12 16:27:34 -0700257 NSString *nsstr_reason = [NSString stringForStdString:event.reason];
258 if ([peer_connection.delegate
259 respondsToSelector:@selector
260 (peerConnection:didChangeLocalCandidate:remoteCandidate:lastReceivedMs:changeReason:)]) {
261 [peer_connection.delegate peerConnection:peer_connection
262 didChangeLocalCandidate:local_candidate
263 remoteCandidate:remote_candidate
264 lastReceivedMs:event.last_data_received_ms
265 changeReason:nsstr_reason];
266 }
267}
268
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300269void PeerConnectionDelegateAdapter::OnAddTrack(
270 rtc::scoped_refptr<RtpReceiverInterface> receiver,
Alex Drake43faee02019-08-12 16:27:34 -0700271 const std::vector<rtc::scoped_refptr<MediaStreamInterface>> &streams) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200272 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Alex Drake43faee02019-08-12 16:27:34 -0700273 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:
274 didAddReceiver:streams:)]) {
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300275 NSMutableArray *mediaStreams = [NSMutableArray arrayWithCapacity:streams.size()];
Alex Drake43faee02019-08-12 16:27:34 -0700276 for (const auto &nativeStream : streams) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200277 RTC_OBJC_TYPE(RTCMediaStream) *mediaStream =
278 [[RTC_OBJC_TYPE(RTCMediaStream) alloc] initWithFactory:peer_connection.factory
279 nativeMediaStream:nativeStream];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300280 [mediaStreams addObject:mediaStream];
281 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200282 RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver =
283 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory
284 nativeRtpReceiver:receiver];
Yura Yaroshevich546d7f92018-02-28 21:06:34 +0300285
286 [peer_connection.delegate peerConnection:peer_connection
287 didAddReceiver:rtpReceiver
288 streams:mediaStreams];
289 }
290}
291
Zeke Chin8de502b2018-08-21 11:41:07 -0700292void PeerConnectionDelegateAdapter::OnRemoveTrack(
293 rtc::scoped_refptr<RtpReceiverInterface> receiver) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200294 RTC_OBJC_TYPE(RTCPeerConnection) *peer_connection = peer_connection_;
Zeke Chin8de502b2018-08-21 11:41:07 -0700295 if ([peer_connection.delegate respondsToSelector:@selector(peerConnection:didRemoveReceiver:)]) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200296 RTC_OBJC_TYPE(RTCRtpReceiver) *rtpReceiver =
297 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:peer_connection.factory
298 nativeRtpReceiver:receiver];
Zeke Chin8de502b2018-08-21 11:41:07 -0700299 [peer_connection.delegate peerConnection:peer_connection didRemoveReceiver:rtpReceiver];
300 }
301}
302
hjonf396f602016-02-11 16:19:06 -0800303} // namespace webrtc
304
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200305@implementation RTC_OBJC_TYPE (RTCPeerConnection) {
306 RTC_OBJC_TYPE(RTCPeerConnectionFactory) * _factory;
307 NSMutableArray<RTC_OBJC_TYPE(RTCMediaStream) *> *_localStreams;
kwibergbfefb032016-05-01 14:53:46 -0700308 std::unique_ptr<webrtc::PeerConnectionDelegateAdapter> _observer;
hjonf396f602016-02-11 16:19:06 -0800309 rtc::scoped_refptr<webrtc::PeerConnectionInterface> _peerConnection;
deadbeef5d0b6d82017-01-09 16:05:28 -0800310 std::unique_ptr<webrtc::MediaConstraints> _nativeConstraints;
ivoc14d5dbe2016-07-04 07:06:55 -0700311 BOOL _hasStartedRtcEventLog;
hjonf396f602016-02-11 16:19:06 -0800312}
313
314@synthesize delegate = _delegate;
Yura Yaroshevichc806c1d2018-06-21 12:51:11 +0300315@synthesize factory = _factory;
hjonf396f602016-02-11 16:19:06 -0800316
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300317- (nullable instancetype)initWithFactory:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
318 configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
319 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
320 delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
hjonf396f602016-02-11 16:19:06 -0800321 NSParameterAssert(factory);
Jonas Oreland285f83d2020-02-07 10:30:08 +0100322 std::unique_ptr<webrtc::PeerConnectionDependencies> dependencies =
323 std::make_unique<webrtc::PeerConnectionDependencies>(nullptr);
324 return [self initWithDependencies:factory
325 configuration:configuration
326 constraints:constraints
327 dependencies:std::move(dependencies)
328 delegate:delegate];
329}
330
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300331- (nullable instancetype)
332 initWithDependencies:(RTC_OBJC_TYPE(RTCPeerConnectionFactory) *)factory
333 configuration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration
334 constraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
335 dependencies:(std::unique_ptr<webrtc::PeerConnectionDependencies>)dependencies
336 delegate:(id<RTC_OBJC_TYPE(RTCPeerConnectionDelegate)>)delegate {
Jonas Oreland285f83d2020-02-07 10:30:08 +0100337 NSParameterAssert(factory);
338 NSParameterAssert(dependencies.get());
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200339 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700340 [configuration createNativeConfiguration]);
341 if (!config) {
342 return nil;
343 }
hjonf396f602016-02-11 16:19:06 -0800344 if (self = [super init]) {
345 _observer.reset(new webrtc::PeerConnectionDelegateAdapter(self));
deadbeef5d0b6d82017-01-09 16:05:28 -0800346 _nativeConstraints = constraints.nativeConstraints;
Jonas Oreland285f83d2020-02-07 10:30:08 +0100347 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(), config.get());
348
349 webrtc::PeerConnectionDependencies deps = std::move(*dependencies.release());
350 deps.observer = _observer.get();
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000351 auto result = factory.nativeFactory->CreatePeerConnectionOrError(*config, std::move(deps));
Jonas Oreland285f83d2020-02-07 10:30:08 +0100352
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000353 if (!result.ok()) {
skvlad588783a2016-08-11 14:29:25 -0700354 return nil;
355 }
Harald Alvestrandf33f7a22021-05-09 14:58:57 +0000356 _peerConnection = result.MoveValue();
Yura Yaroshevich5297bd22018-06-19 12:51:51 +0300357 _factory = factory;
hjonf396f602016-02-11 16:19:06 -0800358 _localStreams = [[NSMutableArray alloc] init];
359 _delegate = delegate;
360 }
361 return self;
362}
363
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200364- (NSArray<RTC_OBJC_TYPE(RTCMediaStream) *> *)localStreams {
hjonf396f602016-02-11 16:19:06 -0800365 return [_localStreams copy];
366}
367
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200368- (RTC_OBJC_TYPE(RTCSessionDescription) *)localDescription {
Taylor Brandstetterc88fe702020-08-03 16:36:16 -0700369 // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
370 return _peerConnection->signaling_thread()->Invoke<RTC_OBJC_TYPE(RTCSessionDescription) *>(
371 RTC_FROM_HERE, [self] {
372 const webrtc::SessionDescriptionInterface *description =
373 _peerConnection->local_description();
374 return description ?
375 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
376 nil;
377 });
hjonf396f602016-02-11 16:19:06 -0800378}
379
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200380- (RTC_OBJC_TYPE(RTCSessionDescription) *)remoteDescription {
Taylor Brandstetterc88fe702020-08-03 16:36:16 -0700381 // It's only safe to operate on SessionDescriptionInterface on the signaling thread.
382 return _peerConnection->signaling_thread()->Invoke<RTC_OBJC_TYPE(RTCSessionDescription) *>(
383 RTC_FROM_HERE, [self] {
384 const webrtc::SessionDescriptionInterface *description =
385 _peerConnection->remote_description();
386 return description ?
387 [[RTC_OBJC_TYPE(RTCSessionDescription) alloc] initWithNativeDescription:description] :
388 nil;
389 });
hjonf396f602016-02-11 16:19:06 -0800390}
391
392- (RTCSignalingState)signalingState {
393 return [[self class]
394 signalingStateForNativeState:_peerConnection->signaling_state()];
395}
396
397- (RTCIceConnectionState)iceConnectionState {
398 return [[self class] iceConnectionStateForNativeState:
399 _peerConnection->ice_connection_state()];
400}
401
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100402- (RTCPeerConnectionState)connectionState {
403 return [[self class] connectionStateForNativeState:_peerConnection->peer_connection_state()];
404}
405
hjonf396f602016-02-11 16:19:06 -0800406- (RTCIceGatheringState)iceGatheringState {
407 return [[self class] iceGatheringStateForNativeState:
408 _peerConnection->ice_gathering_state()];
409}
410
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200411- (BOOL)setConfiguration:(RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
Henrik Boströme06c2dd2016-05-13 13:50:38 +0200412 std::unique_ptr<webrtc::PeerConnectionInterface::RTCConfiguration> config(
hbosa73ca562016-05-17 03:28:58 -0700413 [configuration createNativeConfiguration]);
414 if (!config) {
415 return NO;
416 }
deadbeef5d0b6d82017-01-09 16:05:28 -0800417 CopyConstraintsIntoRtcConfiguration(_nativeConstraints.get(),
418 config.get());
Niels Möller2579f0c2019-08-19 09:58:17 +0200419 return _peerConnection->SetConfiguration(*config).ok();
tkchinaac3eb22016-03-09 21:49:40 -0800420}
421
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200422- (RTC_OBJC_TYPE(RTCConfiguration) *)configuration {
jtteh4eeb5372017-04-03 15:06:37 -0700423 webrtc::PeerConnectionInterface::RTCConfiguration config =
424 _peerConnection->GetConfiguration();
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200425 return [[RTC_OBJC_TYPE(RTCConfiguration) alloc] initWithNativeConfiguration:config];
jtteh4eeb5372017-04-03 15:06:37 -0700426}
427
hjonf396f602016-02-11 16:19:06 -0800428- (void)close {
429 _peerConnection->Close();
430}
431
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200432- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate {
kwibergbfefb032016-05-01 14:53:46 -0700433 std::unique_ptr<const webrtc::IceCandidateInterface> iceCandidate(
hjonf396f602016-02-11 16:19:06 -0800434 candidate.nativeCandidate);
435 _peerConnection->AddIceCandidate(iceCandidate.get());
436}
Yura Yaroshevich2d9f53c2021-03-10 13:03:00 +0300437- (void)addIceCandidate:(RTC_OBJC_TYPE(RTCIceCandidate) *)candidate
438 completionHandler:(void (^)(NSError *_Nullable error))completionHandler {
439 RTC_DCHECK(completionHandler != nil);
Byoungchan Lee8c487572021-08-04 20:55:25 +0900440 _peerConnection->AddIceCandidate(
441 candidate.nativeCandidate, [completionHandler](const auto &error) {
442 if (error.ok()) {
443 completionHandler(nil);
444 } else {
445 NSString *str = [NSString stringForStdString:error.message()];
446 NSError *err = [NSError errorWithDomain:kRTCPeerConnectionErrorDomain
447 code:static_cast<NSInteger>(error.type())
448 userInfo:@{NSLocalizedDescriptionKey : str}];
449 completionHandler(err);
450 }
451 });
Yura Yaroshevich2d9f53c2021-03-10 13:03:00 +0300452}
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200453- (void)removeIceCandidates:(NSArray<RTC_OBJC_TYPE(RTCIceCandidate) *> *)iceCandidates {
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700454 std::vector<cricket::Candidate> candidates;
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200455 for (RTC_OBJC_TYPE(RTCIceCandidate) * iceCandidate in iceCandidates) {
Honghai Zhangda2ba4d2016-05-23 11:53:14 -0700456 std::unique_ptr<const webrtc::IceCandidateInterface> candidate(
457 iceCandidate.nativeCandidate);
458 if (candidate) {
459 candidates.push_back(candidate->candidate());
460 // Need to fill the transport name from the sdp_mid.
461 candidates.back().set_transport_name(candidate->sdp_mid());
462 }
463 }
464 if (!candidates.empty()) {
465 _peerConnection->RemoveIceCandidates(candidates);
466 }
467}
468
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200469- (void)addStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
hjona2f77982016-03-04 07:09:09 -0800470 if (!_peerConnection->AddStream(stream.nativeMediaStream)) {
hjonf396f602016-02-11 16:19:06 -0800471 RTCLogError(@"Failed to add stream: %@", stream);
472 return;
473 }
474 [_localStreams addObject:stream];
475}
476
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200477- (void)removeStream:(RTC_OBJC_TYPE(RTCMediaStream) *)stream {
hjonf396f602016-02-11 16:19:06 -0800478 _peerConnection->RemoveStream(stream.nativeMediaStream);
479 [_localStreams removeObject:stream];
480}
481
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300482- (nullable RTC_OBJC_TYPE(RTCRtpSender) *)addTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
483 streamIds:(NSArray<NSString *> *)streamIds {
Seth Hampson513449e2018-03-06 09:35:56 -0800484 std::vector<std::string> nativeStreamIds;
485 for (NSString *streamId in streamIds) {
486 nativeStreamIds.push_back([streamId UTF8String]);
Steve Anton8cb344a2018-02-27 15:34:53 -0800487 }
488 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenderOrError =
Seth Hampson513449e2018-03-06 09:35:56 -0800489 _peerConnection->AddTrack(track.nativeTrack, nativeStreamIds);
Steve Anton8cb344a2018-02-27 15:34:53 -0800490 if (!nativeSenderOrError.ok()) {
491 RTCLogError(@"Failed to add track %@: %s", track, nativeSenderOrError.error().message());
492 return nil;
493 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200494 return [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
495 nativeRtpSender:nativeSenderOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800496}
497
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200498- (BOOL)removeTrack:(RTC_OBJC_TYPE(RTCRtpSender) *)sender {
Steve Anton8cb344a2018-02-27 15:34:53 -0800499 bool result = _peerConnection->RemoveTrack(sender.nativeRtpSender);
500 if (!result) {
501 RTCLogError(@"Failed to remote track %@", sender);
502 }
503 return result;
504}
505
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300506- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverWithTrack:
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200507 (RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track {
508 return [self addTransceiverWithTrack:track
509 init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
Steve Anton8cb344a2018-02-27 15:34:53 -0800510}
511
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300512- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200513 addTransceiverWithTrack:(RTC_OBJC_TYPE(RTCMediaStreamTrack) *)track
514 init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
Steve Anton8cb344a2018-02-27 15:34:53 -0800515 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
516 _peerConnection->AddTransceiver(track.nativeTrack, init.nativeInit);
517 if (!nativeTransceiverOrError.ok()) {
518 RTCLogError(
519 @"Failed to add transceiver %@: %s", track, nativeTransceiverOrError.error().message());
520 return nil;
521 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200522 return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
523 initWithFactory:self.factory
524 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800525}
526
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300527- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)addTransceiverOfType:(RTCRtpMediaType)mediaType {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200528 return [self addTransceiverOfType:mediaType
529 init:[[RTC_OBJC_TYPE(RTCRtpTransceiverInit) alloc] init]];
Steve Anton8cb344a2018-02-27 15:34:53 -0800530}
531
Yura Yaroshevichd140c8f2021-03-02 23:25:10 +0300532- (nullable RTC_OBJC_TYPE(RTCRtpTransceiver) *)
533 addTransceiverOfType:(RTCRtpMediaType)mediaType
534 init:(RTC_OBJC_TYPE(RTCRtpTransceiverInit) *)init {
Steve Anton8cb344a2018-02-27 15:34:53 -0800535 webrtc::RTCErrorOr<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceiverOrError =
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200536 _peerConnection->AddTransceiver(
537 [RTC_OBJC_TYPE(RTCRtpReceiver) nativeMediaTypeForMediaType:mediaType], init.nativeInit);
Steve Anton8cb344a2018-02-27 15:34:53 -0800538 if (!nativeTransceiverOrError.ok()) {
539 RTCLogError(@"Failed to add transceiver %@: %s",
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200540 [RTC_OBJC_TYPE(RTCRtpReceiver) stringForMediaType:mediaType],
Steve Anton8cb344a2018-02-27 15:34:53 -0800541 nativeTransceiverOrError.error().message());
542 return nil;
543 }
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200544 return [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc]
545 initWithFactory:self.factory
546 nativeRtpTransceiver:nativeTransceiverOrError.MoveValue()];
Steve Anton8cb344a2018-02-27 15:34:53 -0800547}
548
Yura Yaroshevich92d12702021-03-06 23:55:17 +0300549- (void)restartIce {
550 _peerConnection->RestartIce();
551}
552
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200553- (void)offerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300554 completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
555 RTC_DCHECK(completionHandler != nil);
hjonf396f602016-02-11 16:19:06 -0800556 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
557 observer(new rtc::RefCountedObject
558 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200559 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
560 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
561
562 _peerConnection->CreateOffer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800563}
564
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200565- (void)answerForConstraints:(RTC_OBJC_TYPE(RTCMediaConstraints) *)constraints
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300566 completionHandler:(RTCCreateSessionDescriptionCompletionHandler)completionHandler {
567 RTC_DCHECK(completionHandler != nil);
hjonf396f602016-02-11 16:19:06 -0800568 rtc::scoped_refptr<webrtc::CreateSessionDescriptionObserverAdapter>
569 observer(new rtc::RefCountedObject
570 <webrtc::CreateSessionDescriptionObserverAdapter>(completionHandler));
Niels Möllerf06f9232018-08-07 12:32:18 +0200571 webrtc::PeerConnectionInterface::RTCOfferAnswerOptions options;
572 CopyConstraintsIntoOfferAnswerOptions(constraints.nativeConstraints.get(), &options);
573
574 _peerConnection->CreateAnswer(observer, options);
hjonf396f602016-02-11 16:19:06 -0800575}
576
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200577- (void)setLocalDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300578 completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
579 RTC_DCHECK(completionHandler != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300580 rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer(
581 new rtc::RefCountedObject<::SetSessionDescriptionObserver>(completionHandler));
Byoungchan Lee33728152021-08-04 20:54:45 +0900582 _peerConnection->SetLocalDescription(sdp.nativeDescription, observer);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300583}
584
585- (void)setLocalDescriptionWithCompletionHandler:
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300586 (RTCSetSessionDescriptionCompletionHandler)completionHandler {
587 RTC_DCHECK(completionHandler != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300588 rtc::scoped_refptr<webrtc::SetLocalDescriptionObserverInterface> observer(
589 new rtc::RefCountedObject<::SetSessionDescriptionObserver>(completionHandler));
590 _peerConnection->SetLocalDescription(observer);
hjonf396f602016-02-11 16:19:06 -0800591}
592
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200593- (void)setRemoteDescription:(RTC_OBJC_TYPE(RTCSessionDescription) *)sdp
Yura Yaroshevich8bfa2752021-03-10 13:07:27 +0300594 completionHandler:(RTCSetSessionDescriptionCompletionHandler)completionHandler {
595 RTC_DCHECK(completionHandler != nil);
Yura Yaroshevichd6725352021-03-05 18:21:16 +0300596 rtc::scoped_refptr<webrtc::SetRemoteDescriptionObserverInterface> observer(
597 new rtc::RefCountedObject<::SetSessionDescriptionObserver>(completionHandler));
Byoungchan Lee33728152021-08-04 20:54:45 +0900598 _peerConnection->SetRemoteDescription(sdp.nativeDescription, observer);
hjonf396f602016-02-11 16:19:06 -0800599}
600
zstein8b476172017-09-05 14:43:03 -0700601- (BOOL)setBweMinBitrateBps:(nullable NSNumber *)minBitrateBps
602 currentBitrateBps:(nullable NSNumber *)currentBitrateBps
603 maxBitrateBps:(nullable NSNumber *)maxBitrateBps {
Niels Möller9ad1f6f2020-07-13 10:25:41 +0200604 webrtc::BitrateSettings params;
zstein03adb7c2017-08-09 14:29:42 -0700605 if (minBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200606 params.min_bitrate_bps = absl::optional<int>(minBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700607 }
608 if (currentBitrateBps != nil) {
Niels Möller9ad1f6f2020-07-13 10:25:41 +0200609 params.start_bitrate_bps = absl::optional<int>(currentBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700610 }
611 if (maxBitrateBps != nil) {
Danil Chapovalov196100e2018-06-21 10:17:24 +0200612 params.max_bitrate_bps = absl::optional<int>(maxBitrateBps.intValue);
zstein03adb7c2017-08-09 14:29:42 -0700613 }
614 return _peerConnection->SetBitrate(params).ok();
615}
616
ivoc14d5dbe2016-07-04 07:06:55 -0700617- (BOOL)startRtcEventLogWithFilePath:(NSString *)filePath
618 maxSizeInBytes:(int64_t)maxSizeInBytes {
619 RTC_DCHECK(filePath.length);
620 RTC_DCHECK_GT(maxSizeInBytes, 0);
621 RTC_DCHECK(!_hasStartedRtcEventLog);
622 if (_hasStartedRtcEventLog) {
623 RTCLogError(@"Event logging already started.");
624 return NO;
625 }
Niels Möllerdec9f742019-06-03 15:25:20 +0200626 FILE *f = fopen(filePath.UTF8String, "wb");
627 if (!f) {
ivoc14d5dbe2016-07-04 07:06:55 -0700628 RTCLogError(@"Error opening file: %@. Error: %d", filePath, errno);
629 return NO;
630 }
Niels Möller695cf6a2019-05-13 12:27:23 +0200631 // TODO(eladalon): It would be better to not allow negative values into PC.
632 const size_t max_size = (maxSizeInBytes < 0) ? webrtc::RtcEventLog::kUnlimitedOutput :
633 rtc::saturated_cast<size_t>(maxSizeInBytes);
634
635 _hasStartedRtcEventLog = _peerConnection->StartRtcEventLog(
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200636 std::make_unique<webrtc::RtcEventLogOutputFile>(f, max_size));
ivoc14d5dbe2016-07-04 07:06:55 -0700637 return _hasStartedRtcEventLog;
638}
639
640- (void)stopRtcEventLog {
641 _peerConnection->StopRtcEventLog();
642 _hasStartedRtcEventLog = NO;
643}
644
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200645- (RTC_OBJC_TYPE(RTCRtpSender) *)senderWithKind:(NSString *)kind streamId:(NSString *)streamId {
skvladf3569c82016-04-29 15:30:16 -0700646 std::string nativeKind = [NSString stdStringForString:kind];
647 std::string nativeStreamId = [NSString stdStringForString:streamId];
648 rtc::scoped_refptr<webrtc::RtpSenderInterface> nativeSender(
649 _peerConnection->CreateSender(nativeKind, nativeStreamId));
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200650 return nativeSender ? [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
651 nativeRtpSender:nativeSender] :
652 nil;
skvladf3569c82016-04-29 15:30:16 -0700653}
654
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200655- (NSArray<RTC_OBJC_TYPE(RTCRtpSender) *> *)senders {
skvlad79b4b872016-04-08 17:28:55 -0700656 std::vector<rtc::scoped_refptr<webrtc::RtpSenderInterface>> nativeSenders(
657 _peerConnection->GetSenders());
658 NSMutableArray *senders = [[NSMutableArray alloc] init];
659 for (const auto &nativeSender : nativeSenders) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200660 RTC_OBJC_TYPE(RTCRtpSender) *sender =
661 [[RTC_OBJC_TYPE(RTCRtpSender) alloc] initWithFactory:self.factory
662 nativeRtpSender:nativeSender];
skvlad79b4b872016-04-08 17:28:55 -0700663 [senders addObject:sender];
664 }
665 return senders;
666}
667
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200668- (NSArray<RTC_OBJC_TYPE(RTCRtpReceiver) *> *)receivers {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700669 std::vector<rtc::scoped_refptr<webrtc::RtpReceiverInterface>> nativeReceivers(
670 _peerConnection->GetReceivers());
671 NSMutableArray *receivers = [[NSMutableArray alloc] init];
672 for (const auto &nativeReceiver : nativeReceivers) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200673 RTC_OBJC_TYPE(RTCRtpReceiver) *receiver =
674 [[RTC_OBJC_TYPE(RTCRtpReceiver) alloc] initWithFactory:self.factory
675 nativeRtpReceiver:nativeReceiver];
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700676 [receivers addObject:receiver];
677 }
678 return receivers;
679}
680
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200681- (NSArray<RTC_OBJC_TYPE(RTCRtpTransceiver) *> *)transceivers {
Steve Anton8cb344a2018-02-27 15:34:53 -0800682 std::vector<rtc::scoped_refptr<webrtc::RtpTransceiverInterface>> nativeTransceivers(
683 _peerConnection->GetTransceivers());
684 NSMutableArray *transceivers = [[NSMutableArray alloc] init];
Mirko Bonadei739baf02019-01-27 17:29:42 +0100685 for (const auto &nativeTransceiver : nativeTransceivers) {
Mirko Bonadeia81e9c82020-05-04 16:14:32 +0200686 RTC_OBJC_TYPE(RTCRtpTransceiver) *transceiver =
687 [[RTC_OBJC_TYPE(RTCRtpTransceiver) alloc] initWithFactory:self.factory
688 nativeRtpTransceiver:nativeTransceiver];
Steve Anton8cb344a2018-02-27 15:34:53 -0800689 [transceivers addObject:transceiver];
690 }
691 return transceivers;
692}
693
hjonf396f602016-02-11 16:19:06 -0800694#pragma mark - Private
695
696+ (webrtc::PeerConnectionInterface::SignalingState)nativeSignalingStateForState:
697 (RTCSignalingState)state {
698 switch (state) {
699 case RTCSignalingStateStable:
700 return webrtc::PeerConnectionInterface::kStable;
701 case RTCSignalingStateHaveLocalOffer:
702 return webrtc::PeerConnectionInterface::kHaveLocalOffer;
703 case RTCSignalingStateHaveLocalPrAnswer:
704 return webrtc::PeerConnectionInterface::kHaveLocalPrAnswer;
705 case RTCSignalingStateHaveRemoteOffer:
706 return webrtc::PeerConnectionInterface::kHaveRemoteOffer;
707 case RTCSignalingStateHaveRemotePrAnswer:
708 return webrtc::PeerConnectionInterface::kHaveRemotePrAnswer;
709 case RTCSignalingStateClosed:
710 return webrtc::PeerConnectionInterface::kClosed;
711 }
712}
713
714+ (RTCSignalingState)signalingStateForNativeState:
715 (webrtc::PeerConnectionInterface::SignalingState)nativeState {
716 switch (nativeState) {
717 case webrtc::PeerConnectionInterface::kStable:
718 return RTCSignalingStateStable;
719 case webrtc::PeerConnectionInterface::kHaveLocalOffer:
720 return RTCSignalingStateHaveLocalOffer;
721 case webrtc::PeerConnectionInterface::kHaveLocalPrAnswer:
722 return RTCSignalingStateHaveLocalPrAnswer;
723 case webrtc::PeerConnectionInterface::kHaveRemoteOffer:
724 return RTCSignalingStateHaveRemoteOffer;
725 case webrtc::PeerConnectionInterface::kHaveRemotePrAnswer:
726 return RTCSignalingStateHaveRemotePrAnswer;
727 case webrtc::PeerConnectionInterface::kClosed:
728 return RTCSignalingStateClosed;
729 }
730}
731
732+ (NSString *)stringForSignalingState:(RTCSignalingState)state {
733 switch (state) {
734 case RTCSignalingStateStable:
735 return @"STABLE";
736 case RTCSignalingStateHaveLocalOffer:
737 return @"HAVE_LOCAL_OFFER";
738 case RTCSignalingStateHaveLocalPrAnswer:
739 return @"HAVE_LOCAL_PRANSWER";
740 case RTCSignalingStateHaveRemoteOffer:
741 return @"HAVE_REMOTE_OFFER";
742 case RTCSignalingStateHaveRemotePrAnswer:
743 return @"HAVE_REMOTE_PRANSWER";
744 case RTCSignalingStateClosed:
745 return @"CLOSED";
746 }
747}
748
Jonas Olssoncfddbb72018-11-15 16:52:45 +0100749+ (webrtc::PeerConnectionInterface::PeerConnectionState)nativeConnectionStateForState:
750 (RTCPeerConnectionState)state {
751 switch (state) {
752 case RTCPeerConnectionStateNew:
753 return webrtc::PeerConnectionInterface::PeerConnectionState::kNew;
754 case RTCPeerConnectionStateConnecting:
755 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting;
756 case RTCPeerConnectionStateConnected:
757 return webrtc::PeerConnectionInterface::PeerConnectionState::kConnected;
758 case RTCPeerConnectionStateFailed:
759 return webrtc::PeerConnectionInterface::PeerConnectionState::kFailed;
760 case RTCPeerConnectionStateDisconnected:
761 return webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected;
762 case RTCPeerConnectionStateClosed:
763 return webrtc::PeerConnectionInterface::PeerConnectionState::kClosed;
764 }
765}
766
767+ (RTCPeerConnectionState)connectionStateForNativeState:
768 (webrtc::PeerConnectionInterface::PeerConnectionState)nativeState {
769 switch (nativeState) {
770 case webrtc::PeerConnectionInterface::PeerConnectionState::kNew:
771 return RTCPeerConnectionStateNew;
772 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnecting:
773 return RTCPeerConnectionStateConnecting;
774 case webrtc::PeerConnectionInterface::PeerConnectionState::kConnected:
775 return RTCPeerConnectionStateConnected;
776 case webrtc::PeerConnectionInterface::PeerConnectionState::kFailed:
777 return RTCPeerConnectionStateFailed;
778 case webrtc::PeerConnectionInterface::PeerConnectionState::kDisconnected:
779 return RTCPeerConnectionStateDisconnected;
780 case webrtc::PeerConnectionInterface::PeerConnectionState::kClosed:
781 return RTCPeerConnectionStateClosed;
782 }
783}
784
785+ (NSString *)stringForConnectionState:(RTCPeerConnectionState)state {
786 switch (state) {
787 case RTCPeerConnectionStateNew:
788 return @"NEW";
789 case RTCPeerConnectionStateConnecting:
790 return @"CONNECTING";
791 case RTCPeerConnectionStateConnected:
792 return @"CONNECTED";
793 case RTCPeerConnectionStateFailed:
794 return @"FAILED";
795 case RTCPeerConnectionStateDisconnected:
796 return @"DISCONNECTED";
797 case RTCPeerConnectionStateClosed:
798 return @"CLOSED";
799 }
800}
801
hjonf396f602016-02-11 16:19:06 -0800802+ (webrtc::PeerConnectionInterface::IceConnectionState)
803 nativeIceConnectionStateForState:(RTCIceConnectionState)state {
804 switch (state) {
805 case RTCIceConnectionStateNew:
806 return webrtc::PeerConnectionInterface::kIceConnectionNew;
807 case RTCIceConnectionStateChecking:
808 return webrtc::PeerConnectionInterface::kIceConnectionChecking;
809 case RTCIceConnectionStateConnected:
810 return webrtc::PeerConnectionInterface::kIceConnectionConnected;
811 case RTCIceConnectionStateCompleted:
812 return webrtc::PeerConnectionInterface::kIceConnectionCompleted;
813 case RTCIceConnectionStateFailed:
814 return webrtc::PeerConnectionInterface::kIceConnectionFailed;
815 case RTCIceConnectionStateDisconnected:
816 return webrtc::PeerConnectionInterface::kIceConnectionDisconnected;
817 case RTCIceConnectionStateClosed:
818 return webrtc::PeerConnectionInterface::kIceConnectionClosed;
hjon8bbbf2c2016-03-14 13:15:44 -0700819 case RTCIceConnectionStateCount:
hjonf396f602016-02-11 16:19:06 -0800820 return webrtc::PeerConnectionInterface::kIceConnectionMax;
821 }
822}
823
824+ (RTCIceConnectionState)iceConnectionStateForNativeState:
825 (webrtc::PeerConnectionInterface::IceConnectionState)nativeState {
826 switch (nativeState) {
827 case webrtc::PeerConnectionInterface::kIceConnectionNew:
828 return RTCIceConnectionStateNew;
829 case webrtc::PeerConnectionInterface::kIceConnectionChecking:
830 return RTCIceConnectionStateChecking;
831 case webrtc::PeerConnectionInterface::kIceConnectionConnected:
832 return RTCIceConnectionStateConnected;
833 case webrtc::PeerConnectionInterface::kIceConnectionCompleted:
834 return RTCIceConnectionStateCompleted;
835 case webrtc::PeerConnectionInterface::kIceConnectionFailed:
836 return RTCIceConnectionStateFailed;
837 case webrtc::PeerConnectionInterface::kIceConnectionDisconnected:
838 return RTCIceConnectionStateDisconnected;
839 case webrtc::PeerConnectionInterface::kIceConnectionClosed:
840 return RTCIceConnectionStateClosed;
841 case webrtc::PeerConnectionInterface::kIceConnectionMax:
hjon8bbbf2c2016-03-14 13:15:44 -0700842 return RTCIceConnectionStateCount;
hjonf396f602016-02-11 16:19:06 -0800843 }
844}
845
846+ (NSString *)stringForIceConnectionState:(RTCIceConnectionState)state {
847 switch (state) {
848 case RTCIceConnectionStateNew:
849 return @"NEW";
850 case RTCIceConnectionStateChecking:
851 return @"CHECKING";
852 case RTCIceConnectionStateConnected:
853 return @"CONNECTED";
854 case RTCIceConnectionStateCompleted:
855 return @"COMPLETED";
856 case RTCIceConnectionStateFailed:
857 return @"FAILED";
858 case RTCIceConnectionStateDisconnected:
859 return @"DISCONNECTED";
860 case RTCIceConnectionStateClosed:
861 return @"CLOSED";
hjon8bbbf2c2016-03-14 13:15:44 -0700862 case RTCIceConnectionStateCount:
863 return @"COUNT";
hjonf396f602016-02-11 16:19:06 -0800864 }
865}
866
867+ (webrtc::PeerConnectionInterface::IceGatheringState)
868 nativeIceGatheringStateForState:(RTCIceGatheringState)state {
869 switch (state) {
870 case RTCIceGatheringStateNew:
871 return webrtc::PeerConnectionInterface::kIceGatheringNew;
872 case RTCIceGatheringStateGathering:
873 return webrtc::PeerConnectionInterface::kIceGatheringGathering;
874 case RTCIceGatheringStateComplete:
875 return webrtc::PeerConnectionInterface::kIceGatheringComplete;
876 }
877}
878
879+ (RTCIceGatheringState)iceGatheringStateForNativeState:
880 (webrtc::PeerConnectionInterface::IceGatheringState)nativeState {
881 switch (nativeState) {
882 case webrtc::PeerConnectionInterface::kIceGatheringNew:
883 return RTCIceGatheringStateNew;
884 case webrtc::PeerConnectionInterface::kIceGatheringGathering:
885 return RTCIceGatheringStateGathering;
886 case webrtc::PeerConnectionInterface::kIceGatheringComplete:
887 return RTCIceGatheringStateComplete;
888 }
889}
890
891+ (NSString *)stringForIceGatheringState:(RTCIceGatheringState)state {
892 switch (state) {
893 case RTCIceGatheringStateNew:
894 return @"NEW";
895 case RTCIceGatheringStateGathering:
896 return @"GATHERING";
897 case RTCIceGatheringStateComplete:
898 return @"COMPLETE";
899 }
900}
901
902+ (webrtc::PeerConnectionInterface::StatsOutputLevel)
903 nativeStatsOutputLevelForLevel:(RTCStatsOutputLevel)level {
904 switch (level) {
905 case RTCStatsOutputLevelStandard:
906 return webrtc::PeerConnectionInterface::kStatsOutputLevelStandard;
907 case RTCStatsOutputLevelDebug:
908 return webrtc::PeerConnectionInterface::kStatsOutputLevelDebug;
909 }
910}
911
hjonf396f602016-02-11 16:19:06 -0800912- (rtc::scoped_refptr<webrtc::PeerConnectionInterface>)nativePeerConnection {
913 return _peerConnection;
914}
915
916@end